",
+ "isFunction": false,
+ "isFunctionDeclaration": false,
+ "isRequired": false,
+ "constant": false,
+ "reactive": false
+ }
+ ],
+ "moduleExports": [],
+ "slots": [
+ { "name": "__default__", "default": true, "slot_props": "{}" },
+ { "name": "action", "default": false, "slot_props": "{}" }
+ ],
+ "events": [
+ { "type": "forwarded", "name": "click", "element": "svelte:element" }
+ ],
+ "typedefs": []
+ },
{
"moduleName": "Content",
"filePath": "src/UIShell/Content.svelte",
diff --git a/docs/src/pages/components/ContainedList.svx b/docs/src/pages/components/ContainedList.svx
new file mode 100644
index 0000000000..0db62cd71c
--- /dev/null
+++ b/docs/src/pages/components/ContainedList.svx
@@ -0,0 +1,122 @@
+
+
+## Default
+
+The `ContainedList` component is used to display a list of items in a container.
+
+It uses a `md` size by default.
+
+
+ Item 1
+ Item 2
+ Item 3
+
+
+## Small size
+
+
+ Item 1
+ Item 2
+ Item 3
+
+
+## Large size
+
+
+ Item 1
+ Item 2
+ Item 3
+
+
+## Extra-large size
+
+
+ Item 1
+ Item 2
+ Item 3
+
+
+## Inset items
+
+
+ Item 1
+ Item 2
+ Item 3
+
+
+## Disclosed
+
+Set `kind="disclosed"` for the list title to be sticky positioned.
+
+When scrolling, the list title will stick to the top of the container.
+
+
+
+ {#each Array.from({ length: 6 }) as i}
+ Item
+ {/each}
+
+
+ {#each Array.from({ length: 6 }) as i}
+ Item
+ {/each}
+
+
+
+## With icons
+
+
+ Item 1
+ Item 2
+ Item 3
+
+
+## With expandable search
+
+Use the `action` slot to add an expandable search.
+
+
+
+ Item 1
+ Item 2
+ Item 3
+
+
+## Interactive items
+
+Set `interactive` to make the items render as a `button`.
+
+
+ console.log('click')}>
+ Item 1
+
+ Item 2
+ Item 3
+
+
+## Interactive items with actions
+
+Similarly to `ContainedList`, you can add an action to `ContainedListItem` using the `action` slot.
+
+
+ console.log('click')}>
+ Item 1
+
+ Item 2
+
+ Item 3
+
+
+
diff --git a/src/ContainedList/ContainedList.svelte b/src/ContainedList/ContainedList.svelte
new file mode 100644
index 0000000000..591bcb84c8
--- /dev/null
+++ b/src/ContainedList/ContainedList.svelte
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+ {labelText}
+
+
+ {#if $$slots.action}
+
+
+
+ {/if}
+
+
+
diff --git a/src/ContainedList/ContainedListItem.svelte b/src/ContainedList/ContainedListItem.svelte
new file mode 100644
index 0000000000..c0c338f5b8
--- /dev/null
+++ b/src/ContainedList/ContainedListItem.svelte
@@ -0,0 +1,49 @@
+
+
+
+
+
+ {#if icon}
+
+
+
+ {/if}
+
+
+ {#if $$slots.action}
+
+
+
+ {/if}
+
diff --git a/src/ContainedList/index.js b/src/ContainedList/index.js
new file mode 100644
index 0000000000..e9e8d1ce02
--- /dev/null
+++ b/src/ContainedList/index.js
@@ -0,0 +1,2 @@
+export { default as ContainedList } from "./ContainedList.svelte";
+export { default as ContainedListItem } from "./ContainedListItem.svelte";
diff --git a/src/index.js b/src/index.js
index 4e2cfd0a52..9cb2ce9eed 100644
--- a/src/index.js
+++ b/src/index.js
@@ -22,6 +22,7 @@ export {
ModalBody,
ModalFooter,
} from "./ComposedModal";
+export { ContainedList, ContainedListItem } from "./ContainedList";
export { CodeSnippet, CodeSnippetSkeleton } from "./CodeSnippet";
export {
DataTable,
diff --git a/tests/ContainedList.test.svelte b/tests/ContainedList.test.svelte
new file mode 100644
index 0000000000..d59f637a0b
--- /dev/null
+++ b/tests/ContainedList.test.svelte
@@ -0,0 +1,9 @@
+
+
+
+ Title
+ Item 1
+
+
diff --git a/types/ContainedList/ContainedList.svelte.d.ts b/types/ContainedList/ContainedList.svelte.d.ts
new file mode 100644
index 0000000000..47e0a847f2
--- /dev/null
+++ b/types/ContainedList/ContainedList.svelte.d.ts
@@ -0,0 +1,38 @@
+import type { SvelteComponentTyped } from "svelte";
+
+export interface ContainedListProps {
+ /**
+ * @default "on-page"
+ */
+ kind?: "on-page" | "disclosed";
+
+ /**
+ * Specify the label text
+ * @default ""
+ */
+ labelText?: string;
+
+ /**
+ * Specify the size of the list
+ * @default "md"
+ */
+ size?: "sm" | "md" | "lg" | "xl";
+
+ /**
+ * Set to `true` for lines between list items to be inset.
+ * @default false
+ */
+ inset?: boolean;
+
+ /**
+ * Set an id for the list
+ * @default "ccs-" + Math.random().toString(36)
+ */
+ id?: string;
+}
+
+export default class ContainedList extends SvelteComponentTyped<
+ ContainedListProps,
+ Record,
+ { default: {}; action: {}; labelText: {} }
+> {}
diff --git a/types/ContainedList/ContainedListItem.svelte.d.ts b/types/ContainedList/ContainedListItem.svelte.d.ts
new file mode 100644
index 0000000000..74fdc79dd0
--- /dev/null
+++ b/types/ContainedList/ContainedListItem.svelte.d.ts
@@ -0,0 +1,28 @@
+import type { SvelteComponentTyped } from "svelte";
+
+export interface ContainedListItemProps {
+ /**
+ * Set to `true` to render a `button` element instead of a `div`
+ * @default false
+ */
+ interactive?: boolean;
+
+ /**
+ * Set to `true` to disable the list item.
+ * @default false
+ */
+ disabled?: boolean;
+
+ /**
+ * Specify the icon to render
+ * Icon is rendered to the left of the label text
+ * @default undefined
+ */
+ icon?: typeof import("svelte").SvelteComponent;
+}
+
+export default class ContainedListItem extends SvelteComponentTyped<
+ ContainedListItemProps,
+ { click: WindowEventMap["click"] },
+ { default: {}; action: {} }
+> {}
diff --git a/types/index.d.ts b/types/index.d.ts
index c1403334e3..268427f7ea 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -26,6 +26,8 @@ export { default as ComposedModal } from "./ComposedModal/ComposedModal.svelte";
export { default as ModalHeader } from "./ComposedModal/ModalHeader.svelte";
export { default as ModalBody } from "./ComposedModal/ModalBody.svelte";
export { default as ModalFooter } from "./ComposedModal/ModalFooter.svelte";
+export { default as ContainedList } from "./ContainedList/ContainedList.svelte";
+export { default as ContainedListItem } from "./ContainedList/ContainedListItem.svelte";
export { default as CodeSnippet } from "./CodeSnippet/CodeSnippet.svelte";
export { default as CodeSnippetSkeleton } from "./CodeSnippet/CodeSnippetSkeleton.svelte";
export { default as DataTable } from "./DataTable/DataTable.svelte";