@cfasim-ui/components 0.7.7 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/Box/Box.d.ts +7 -11
  2. package/dist/Button/Button.d.ts +7 -11
  3. package/dist/ButtonGroup/ButtonGroup.d.ts +8 -12
  4. package/dist/Container/Container.d.ts +7 -11
  5. package/dist/Expander/Expander.d.ts +12 -14
  6. package/dist/Grid/Grid.d.ts +6 -5
  7. package/dist/Hint/Hint.d.ts +2 -1
  8. package/dist/Icon/Icon.d.ts +3 -2
  9. package/dist/LightDarkToggle/LightDarkToggle.d.ts +2 -1
  10. package/dist/MultiSelect/MultiSelect.d.ts +6 -6
  11. package/dist/NumberInput/NumberInput.d.ts +13 -11
  12. package/dist/ParamEditor/ParamEditor.d.ts +3 -2
  13. package/dist/ParamEditor/ParamEditorImpl.d.ts +3 -5
  14. package/dist/{ParamEditorImpl-D0xZTyAN.js → ParamEditorImpl-CkElC6PI.js} +3075 -3041
  15. package/dist/SelectBox/SelectBox.d.ts +8 -6
  16. package/dist/{SelectBox-CByXZfaC.js → SelectBox-Df8dE2r-.js} +6 -6
  17. package/dist/SidebarLayout/SidebarLayout.d.ts +21 -20
  18. package/dist/Spinner/Spinner.d.ts +3 -2
  19. package/dist/TextInput/TextInput.d.ts +7 -5
  20. package/dist/Toggle/Toggle.d.ts +8 -6
  21. package/dist/ToggleGroup/ToggleGroup.d.ts +8 -6
  22. package/dist/_internal/FieldLabel.d.ts +2 -1
  23. package/dist/index.js +20 -20
  24. package/docs/Box.md +49 -0
  25. package/docs/Button.md +67 -0
  26. package/docs/ButtonGroup.md +64 -0
  27. package/docs/Container.md +103 -0
  28. package/docs/Expander.md +34 -0
  29. package/docs/Grid.md +170 -0
  30. package/docs/Hint.md +29 -0
  31. package/docs/Icon.md +188 -0
  32. package/docs/MultiSelect.md +143 -0
  33. package/docs/NumberInput.md +485 -0
  34. package/docs/ParamEditor.md +97 -0
  35. package/docs/SelectBox.md +182 -0
  36. package/docs/SidebarLayout.md +106 -0
  37. package/docs/Spinner.md +51 -0
  38. package/docs/TextInput.md +83 -0
  39. package/docs/Toggle.md +81 -0
  40. package/docs/ToggleGroup.md +163 -0
  41. package/docs/index.json +194 -0
  42. package/package.json +24 -20
  43. package/src/Box/Box.md +41 -0
  44. package/src/Box/Box.vue +52 -0
  45. package/src/Button/Button.md +59 -0
  46. package/src/Button/Button.vue +81 -0
  47. package/src/ButtonGroup/ButtonGroup.md +62 -0
  48. package/src/ButtonGroup/ButtonGroup.vue +91 -0
  49. package/src/Container/Container.md +99 -0
  50. package/src/Container/Container.vue +62 -0
  51. package/src/Expander/Expander.md +23 -0
  52. package/src/Expander/Expander.vue +95 -0
  53. package/src/Grid/Grid.md +175 -0
  54. package/src/Grid/Grid.vue +145 -0
  55. package/src/Hint/Hint.md +24 -0
  56. package/src/Hint/Hint.vue +83 -0
  57. package/src/Icon/Icon.md +176 -0
  58. package/src/Icon/Icon.vue +104 -0
  59. package/src/Icon/defaultIcons.ts +92 -0
  60. package/src/Icon/github.svg +1 -0
  61. package/src/Icon/registry.ts +68 -0
  62. package/src/LightDarkToggle/LightDarkToggle.vue +49 -0
  63. package/src/MultiSelect/MultiSelect.md +142 -0
  64. package/src/MultiSelect/MultiSelect.vue +279 -0
  65. package/src/NumberInput/NumberInput.md +455 -0
  66. package/src/NumberInput/NumberInput.vue +575 -0
  67. package/src/ParamEditor/ParamEditor.md +87 -0
  68. package/src/ParamEditor/ParamEditor.vue +43 -0
  69. package/src/ParamEditor/ParamEditorImpl.vue +358 -0
  70. package/src/SelectBox/SelectBox.md +169 -0
  71. package/src/SelectBox/SelectBox.vue +260 -0
  72. package/src/SidebarLayout/SidebarLayout.md +106 -0
  73. package/src/SidebarLayout/SidebarLayout.vue +468 -0
  74. package/src/Spinner/Spinner.md +45 -0
  75. package/src/Spinner/Spinner.vue +55 -0
  76. package/src/TextInput/TextInput.md +68 -0
  77. package/src/TextInput/TextInput.vue +54 -0
  78. package/src/Toggle/Toggle.md +68 -0
  79. package/src/Toggle/Toggle.vue +81 -0
  80. package/src/ToggleGroup/ToggleGroup.md +158 -0
  81. package/src/ToggleGroup/ToggleGroup.vue +138 -0
  82. package/src/_internal/FieldLabel.vue +27 -0
  83. package/src/_internal/field.ts +27 -0
  84. package/src/_internal/gap.ts +17 -0
  85. package/src/_internal/input.css +54 -0
  86. package/src/_internal/listbox.css +53 -0
  87. package/src/env.d.ts +4 -0
  88. package/src/index.ts +33 -0
  89. package/src/svg.d.ts +5 -0
@@ -0,0 +1,68 @@
1
+ # Toggle
2
+
3
+ A boolean switch built on reka-ui.
4
+
5
+ ## Examples
6
+
7
+ <script setup>
8
+ import { ref } from 'vue'
9
+ const enabled = ref(false)
10
+ const disabled = ref(true)
11
+ </script>
12
+
13
+ ### Basic
14
+
15
+ <ComponentDemo>
16
+ <Toggle v-model="enabled" label="Enable vaccination" />
17
+
18
+ <template #code>
19
+
20
+ ```vue
21
+ <script setup>
22
+ import { ref } from "vue";
23
+ const enabled = ref(false);
24
+ </script>
25
+
26
+ <Toggle v-model="enabled" label="Enable vaccination" />
27
+ ```
28
+
29
+ </template>
30
+ </ComponentDemo>
31
+
32
+ ### With hint
33
+
34
+ <ComponentDemo>
35
+ <Toggle
36
+ v-model="enabled"
37
+ label="Enable isolation"
38
+ hint="Whether symptomatic individuals are isolated"
39
+ />
40
+
41
+ <template #code>
42
+
43
+ ```vue
44
+ <Toggle
45
+ v-model="enabled"
46
+ label="Enable isolation"
47
+ hint="Whether symptomatic individuals are isolated"
48
+ />
49
+ ```
50
+
51
+ </template>
52
+ </ComponentDemo>
53
+
54
+ ### Disabled
55
+
56
+ <ComponentDemo>
57
+ <Toggle v-model="disabled" label="Locked setting" :disabled="true" />
58
+
59
+ <template #code>
60
+
61
+ ```vue
62
+ <Toggle v-model="value" label="Locked setting" :disabled="true" />
63
+ ```
64
+
65
+ </template>
66
+ </ComponentDemo>
67
+
68
+ <!--@include: ./_api/toggle.md-->
@@ -0,0 +1,81 @@
1
+ <script setup lang="ts">
2
+ import { SwitchRoot, SwitchThumb, useId } from "reka-ui";
3
+ import Hint from "../Hint/Hint.vue";
4
+
5
+ const model = defineModel<boolean>();
6
+
7
+ const props = defineProps<{
8
+ label: string;
9
+ hint?: string;
10
+ disabled?: boolean;
11
+ }>();
12
+
13
+ const id = useId();
14
+ </script>
15
+
16
+ <template>
17
+ <div class="toggle">
18
+ <label :for="id">{{ label }}</label>
19
+ <Hint v-if="props.hint" :text="props.hint" />
20
+ <SwitchRoot :id="id" v-model="model" :disabled="disabled" class="switch">
21
+ <SwitchThumb class="thumb" />
22
+ </SwitchRoot>
23
+ </div>
24
+ </template>
25
+
26
+ <style scoped>
27
+ .toggle {
28
+ display: flex;
29
+ align-items: center;
30
+ gap: 0.5em;
31
+ }
32
+
33
+ .toggle label {
34
+ user-select: none;
35
+ }
36
+
37
+ .switch {
38
+ --switch-w: 2.25em;
39
+ --switch-h: 1.25em;
40
+ --thumb-size: 1em;
41
+ --thumb-offset: 0.125em;
42
+
43
+ position: relative;
44
+ width: var(--switch-w);
45
+ height: var(--switch-h);
46
+ flex-shrink: 0;
47
+ background: var(--color-border-hover);
48
+ border-radius: var(--switch-h);
49
+ border: none;
50
+ padding: 0;
51
+ cursor: pointer;
52
+ transition: background 0.15s;
53
+ }
54
+
55
+ .switch[data-state="checked"] {
56
+ background: var(--color-primary);
57
+ }
58
+
59
+ .switch[data-disabled] {
60
+ opacity: 0.5;
61
+ cursor: not-allowed;
62
+ }
63
+
64
+ .thumb {
65
+ display: block;
66
+ width: var(--thumb-size);
67
+ height: var(--thumb-size);
68
+ background: white;
69
+ border-radius: 50%;
70
+ position: absolute;
71
+ top: var(--thumb-offset);
72
+ left: var(--thumb-offset);
73
+ transition: transform 0.15s;
74
+ }
75
+
76
+ .switch[data-state="checked"] .thumb {
77
+ transform: translateX(
78
+ calc(var(--switch-w) - var(--thumb-size) - var(--thumb-offset) * 2)
79
+ );
80
+ }
81
+ </style>
@@ -0,0 +1,158 @@
1
+ ---
2
+ keywords:
3
+ [
4
+ toggle group,
5
+ segmented control,
6
+ single select,
7
+ multi select,
8
+ button group,
9
+ radio,
10
+ pressed,
11
+ ]
12
+ ---
13
+
14
+ # ToggleGroup
15
+
16
+ A segmented control that looks like a [`ButtonGroup`](./button-group) but tracks
17
+ which item(s) are pressed. By default it is single-select (like a radio group);
18
+ add `multiple` to let several items be pressed at once. Built on
19
+ [reka-ui's ToggleGroup](https://reka-ui.com/docs/components/toggle-group).
20
+
21
+ ## Examples
22
+
23
+ ### Single select
24
+
25
+ `v-model` holds the pressed value (a `string`). Clicking the active item again
26
+ clears the selection.
27
+
28
+ <script setup>
29
+ import { ref } from 'vue'
30
+ const interval = ref('weekly')
31
+ const days = ref(['mon', 'wed'])
32
+ </script>
33
+
34
+ <ComponentDemo>
35
+ <ToggleGroup
36
+ v-model="interval"
37
+ label="Interval"
38
+ :options="[
39
+ { value: 'daily', label: 'Daily' },
40
+ { value: 'weekly', label: 'Weekly' },
41
+ { value: 'monthly', label: 'Monthly' },
42
+ ]"
43
+ />
44
+ <p>Selected: {{ interval }}</p>
45
+
46
+ <template #code>
47
+
48
+ ```vue
49
+ <script setup>
50
+ import { ref } from "vue";
51
+ const interval = ref("weekly");
52
+ </script>
53
+
54
+ <ToggleGroup
55
+ v-model="interval"
56
+ label="Interval"
57
+ :options="[
58
+ { value: 'daily', label: 'Daily' },
59
+ { value: 'weekly', label: 'Weekly' },
60
+ { value: 'monthly', label: 'Monthly' },
61
+ ]"
62
+ />
63
+ ```
64
+
65
+ </template>
66
+ </ComponentDemo>
67
+
68
+ ### Multiple select
69
+
70
+ With `multiple`, `v-model` is a `string[]` and any number of items can be
71
+ pressed at once.
72
+
73
+ <ComponentDemo>
74
+ <ToggleGroup
75
+ v-model="days"
76
+ multiple
77
+ label="Active days"
78
+ :options="[
79
+ { value: 'mon', label: 'Mon' },
80
+ { value: 'tue', label: 'Tue' },
81
+ { value: 'wed', label: 'Wed' },
82
+ { value: 'thu', label: 'Thu' },
83
+ { value: 'fri', label: 'Fri' },
84
+ ]"
85
+ />
86
+ <p>Selected: {{ days.join(', ') || 'none' }}</p>
87
+
88
+ <template #code>
89
+
90
+ ```vue
91
+ <script setup>
92
+ import { ref } from "vue";
93
+ const days = ref(["mon", "wed"]);
94
+ </script>
95
+
96
+ <ToggleGroup
97
+ v-model="days"
98
+ multiple
99
+ label="Active days"
100
+ :options="[
101
+ { value: 'mon', label: 'Mon' },
102
+ { value: 'tue', label: 'Tue' },
103
+ { value: 'wed', label: 'Wed' },
104
+ { value: 'thu', label: 'Thu' },
105
+ { value: 'fri', label: 'Fri' },
106
+ ]"
107
+ />
108
+ ```
109
+
110
+ </template>
111
+ </ComponentDemo>
112
+
113
+ ### Vertical and disabled options
114
+
115
+ Set `orientation="vertical"` to stack the items, and mark individual options
116
+ `disabled`.
117
+
118
+ <ComponentDemo>
119
+ <ToggleGroup
120
+ model-value="map"
121
+ orientation="vertical"
122
+ aria-label="View"
123
+ :options="[
124
+ { value: 'map', label: 'Map' },
125
+ { value: 'chart', label: 'Chart' },
126
+ { value: 'table', label: 'Table', disabled: true },
127
+ ]"
128
+ />
129
+
130
+ <template #code>
131
+
132
+ ```vue
133
+ <ToggleGroup
134
+ v-model="view"
135
+ orientation="vertical"
136
+ aria-label="View"
137
+ :options="[
138
+ { value: 'map', label: 'Map' },
139
+ { value: 'chart', label: 'Chart' },
140
+ { value: 'table', label: 'Table', disabled: true },
141
+ ]"
142
+ />
143
+ ```
144
+
145
+ </template>
146
+ </ComponentDemo>
147
+
148
+ <!--@include: ./_api/toggle-group.md-->
149
+
150
+ ### ToggleGroupOption
151
+
152
+ ```ts
153
+ interface ToggleGroupOption {
154
+ value: string;
155
+ label: string;
156
+ disabled?: boolean;
157
+ }
158
+ ```
@@ -0,0 +1,138 @@
1
+ <script setup lang="ts">
2
+ import { ToggleGroupItem, ToggleGroupRoot } from "reka-ui";
3
+ import { computed } from "vue";
4
+ import FieldLabel from "../_internal/FieldLabel.vue";
5
+ import { useField, type FieldProps } from "../_internal/field";
6
+
7
+ export interface ToggleGroupOption {
8
+ value: string;
9
+ label: string;
10
+ disabled?: boolean;
11
+ }
12
+
13
+ // `string` in single mode, `string[]` in multiple mode.
14
+ const model = defineModel<string | string[]>();
15
+
16
+ interface Props extends FieldProps {
17
+ options: ToggleGroupOption[];
18
+ multiple?: boolean;
19
+ disabled?: boolean;
20
+ orientation?: "horizontal" | "vertical";
21
+ }
22
+
23
+ const props = withDefaults(defineProps<Props>(), {
24
+ orientation: "horizontal",
25
+ });
26
+
27
+ const { labelId, ariaProps } = useField(props);
28
+ const type = computed<"single" | "multiple">(() =>
29
+ props.multiple ? "multiple" : "single",
30
+ );
31
+ </script>
32
+
33
+ <template>
34
+ <div class="toggle-group-field">
35
+ <FieldLabel
36
+ class="toggle-group-label"
37
+ :label="label"
38
+ :label-id="labelId"
39
+ :hide-label="hideLabel"
40
+ :hint="hint"
41
+ />
42
+ <ToggleGroupRoot
43
+ v-model="model"
44
+ :type="type"
45
+ :disabled="disabled"
46
+ :orientation="orientation"
47
+ :class="['toggle-group', `toggle-group--${orientation}`]"
48
+ v-bind="ariaProps"
49
+ >
50
+ <ToggleGroupItem
51
+ v-for="opt in options"
52
+ :key="opt.value"
53
+ :value="opt.value"
54
+ :disabled="opt.disabled"
55
+ class="toggle-group-item"
56
+ >
57
+ {{ opt.label }}
58
+ </ToggleGroupItem>
59
+ </ToggleGroupRoot>
60
+ </div>
61
+ </template>
62
+
63
+ <style scoped>
64
+ .toggle-group-field {
65
+ display: flex;
66
+ flex-direction: column;
67
+ gap: 0.25em;
68
+ align-items: flex-start;
69
+ }
70
+
71
+ .toggle-group-label {
72
+ display: flex;
73
+ align-items: center;
74
+ gap: 0.25em;
75
+ font-size: var(--font-size-sm);
76
+ }
77
+
78
+ .toggle-group {
79
+ display: inline-flex;
80
+ /* 1px gaps reveal the group background as dividers between items. */
81
+ gap: 1px;
82
+ background: var(--color-border);
83
+ border: 1px solid var(--color-border);
84
+ border-radius: 0.375em;
85
+ /* Clip items to the rounded outer corners. Focus uses an inset outline
86
+ * (below) so it isn't clipped away. */
87
+ overflow: hidden;
88
+ }
89
+
90
+ .toggle-group--vertical {
91
+ flex-direction: column;
92
+ }
93
+
94
+ .toggle-group-item {
95
+ appearance: none;
96
+ display: inline-flex;
97
+ align-items: center;
98
+ justify-content: center;
99
+ min-height: 2.5em;
100
+ padding: 0 1em;
101
+ margin: 0;
102
+ border: none;
103
+ background: var(--color-bg-0);
104
+ color: var(--color-text);
105
+ font: inherit;
106
+ font-size: var(--font-size-sm);
107
+ font-weight: 500;
108
+ white-space: nowrap;
109
+ cursor: pointer;
110
+ transition:
111
+ background var(--transition-fast),
112
+ color var(--transition-fast);
113
+ }
114
+
115
+ .toggle-group-item:hover:not([data-disabled]) {
116
+ background: var(--color-bg-2);
117
+ }
118
+
119
+ .toggle-group-item[data-state="on"] {
120
+ background: var(--color-primary);
121
+ color: var(--color-text-on-primary);
122
+ }
123
+
124
+ .toggle-group-item[data-state="on"]:hover:not([data-disabled]) {
125
+ background: var(--color-primary-hover);
126
+ }
127
+
128
+ .toggle-group-item:focus-visible {
129
+ outline: 2px solid var(--color-primary);
130
+ outline-offset: -2px;
131
+ z-index: 1;
132
+ }
133
+
134
+ .toggle-group-item[data-disabled] {
135
+ opacity: 0.5;
136
+ cursor: not-allowed;
137
+ }
138
+ </style>
@@ -0,0 +1,27 @@
1
+ <script setup lang="ts">
2
+ import Hint from "../Hint/Hint.vue";
3
+
4
+ // The visible label for a form field, with the shared hideLabel/hint
5
+ // behavior. Renders nothing without a `label`; the parent supplies its
6
+ // own class via fallthrough attrs so existing scoped styles keep working.
7
+ defineProps<{
8
+ label?: string;
9
+ labelId?: string;
10
+ hideLabel?: boolean;
11
+ hint?: string;
12
+ /** `for` attribute, for fields whose control is a real labelable element. */
13
+ htmlFor?: string;
14
+ }>();
15
+ </script>
16
+
17
+ <template>
18
+ <label
19
+ v-if="label"
20
+ :id="labelId"
21
+ :for="htmlFor"
22
+ :class="{ 'visually-hidden': hideLabel }"
23
+ >
24
+ {{ label }}
25
+ <Hint v-if="hint && !hideLabel" :text="hint" />
26
+ </label>
27
+ </template>
@@ -0,0 +1,27 @@
1
+ import { computed } from "vue";
2
+ import { useId } from "reka-ui";
3
+
4
+ /** Props shared by every labeled form field. */
5
+ export interface FieldProps {
6
+ label?: string;
7
+ /** Visually hide the label while keeping it for assistive tech. */
8
+ hideLabel?: boolean;
9
+ /** Accessible name used when no visible `label` is provided. */
10
+ ariaLabel?: string;
11
+ hint?: string;
12
+ }
13
+
14
+ /**
15
+ * Generated field/label ids plus the aria attributes that point a control
16
+ * at its label: `aria-labelledby` when a visible `label` exists, else
17
+ * `aria-label`. Spread onto the control with `v-bind="ariaProps.value"`.
18
+ */
19
+ export function useField(props: FieldProps) {
20
+ const id = useId();
21
+ const labelId = `${id}-label`;
22
+ const ariaProps = computed(() => ({
23
+ "aria-labelledby": props.label ? labelId : undefined,
24
+ "aria-label": !props.label ? props.ariaLabel : undefined,
25
+ }));
26
+ return { id, labelId, ariaProps };
27
+ }
@@ -0,0 +1,17 @@
1
+ export type GapToken = "none" | "small" | "medium" | "large";
2
+
3
+ const GAP_TOKENS: Record<GapToken, string> = {
4
+ none: "0",
5
+ small: "var(--space-2)",
6
+ medium: "var(--space-4)",
7
+ large: "var(--space-6)",
8
+ };
9
+
10
+ export function resolveGap(
11
+ gap: GapToken | string | undefined,
12
+ fallback: GapToken = "medium",
13
+ ): string {
14
+ if (gap == null) return GAP_TOKENS[fallback];
15
+ if (gap in GAP_TOKENS) return GAP_TOKENS[gap as GapToken];
16
+ return gap;
17
+ }
@@ -0,0 +1,54 @@
1
+ /* Shared text-field skin for TextInput/NumberInput. Global (not scoped)
2
+ * so both components can use one copy; prefixed to avoid consumer
3
+ * collisions. */
4
+
5
+ .cfasim-input-label {
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: 0.25em;
9
+ font-size: var(--font-size-sm);
10
+ }
11
+
12
+ .cfasim-input-label-row {
13
+ display: flex;
14
+ align-items: center;
15
+ justify-content: space-between;
16
+ }
17
+
18
+ .cfasim-input {
19
+ display: block;
20
+ width: 100%;
21
+ height: 2.5em;
22
+ padding: 0 0.75em;
23
+ font-size: inherit;
24
+ background-color: var(--color-bg-0);
25
+ color: var(--color-text);
26
+ border: 1px solid var(--color-border);
27
+ border-radius: 0.375em;
28
+ transition:
29
+ border-color var(--transition-fast),
30
+ box-shadow var(--transition-fast);
31
+ }
32
+
33
+ .cfasim-input:hover {
34
+ border-color: var(--color-border-hover);
35
+ }
36
+
37
+ .cfasim-input:focus {
38
+ outline: none;
39
+ border-color: var(--color-border-focus);
40
+ box-shadow: var(--shadow-focus);
41
+ }
42
+
43
+ .cfasim-input[aria-invalid="true"] {
44
+ border-color: var(--color-error);
45
+ }
46
+
47
+ .cfasim-input[aria-invalid="true"]:focus {
48
+ border-color: var(--color-error);
49
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-error) 25%, transparent);
50
+ }
51
+
52
+ .cfasim-input::placeholder {
53
+ color: var(--color-text-tertiary);
54
+ }
@@ -0,0 +1,53 @@
1
+ /* Shared skin for the SelectBox/MultiSelect dropdown (reka-ui Select and
2
+ * Combobox portals render outside the component, so these are global).
3
+ * Sizing (width/max-height from the reka trigger vars) stays per-component. */
4
+
5
+ .cfasim-listbox-content {
6
+ z-index: 100;
7
+ background: var(--color-bg-0);
8
+ border: 1px solid var(--color-border);
9
+ border-radius: 0.25em;
10
+ box-shadow:
11
+ 0 4px 6px -1px rgba(0, 0, 0, 0.1),
12
+ 0 2px 4px -2px rgba(0, 0, 0, 0.1);
13
+ }
14
+
15
+ .cfasim-listbox-viewport {
16
+ padding: 0.25em;
17
+ }
18
+
19
+ .cfasim-listbox-empty {
20
+ padding: 0.5em;
21
+ font-size: var(--font-size-sm);
22
+ color: var(--color-text-secondary);
23
+ text-align: center;
24
+ }
25
+
26
+ .cfasim-listbox-item {
27
+ display: flex;
28
+ align-items: center;
29
+ justify-content: space-between;
30
+ gap: 0.5em;
31
+ padding: 0.25em 0.5em;
32
+ border-radius: 0.25em;
33
+ font-size: var(--font-size-sm);
34
+ white-space: nowrap;
35
+ cursor: pointer;
36
+ user-select: none;
37
+ outline: none;
38
+ }
39
+
40
+ .cfasim-listbox-item[data-highlighted] {
41
+ background: var(--color-primary);
42
+ color: white;
43
+ }
44
+
45
+ .cfasim-listbox-item[data-state="checked"] {
46
+ font-weight: 600;
47
+ }
48
+
49
+ .cfasim-listbox-indicator {
50
+ display: flex;
51
+ align-items: center;
52
+ flex-shrink: 0;
53
+ }
package/src/env.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ // Ambient declaration for side-effect CSS imports (e.g. `import "./x.css"`).
2
+ // Required since TypeScript 6, which errors (TS2882) on side-effect imports
3
+ // without a module declaration.
4
+ declare module "*.css";
package/src/index.ts ADDED
@@ -0,0 +1,33 @@
1
+ export { default as Box } from "./Box/Box.vue";
2
+ export type { BoxVariant } from "./Box/Box.vue";
3
+ export { default as Button } from "./Button/Button.vue";
4
+ export { default as ButtonGroup } from "./ButtonGroup/ButtonGroup.vue";
5
+ export { default as Container } from "./Container/Container.vue";
6
+ export type { ContainerGap } from "./Container/Container.vue";
7
+ export { default as Expander } from "./Expander/Expander.vue";
8
+ export { default as Grid } from "./Grid/Grid.vue";
9
+ export type { GridCols, GridGap } from "./Grid/Grid.vue";
10
+ export { default as Hint } from "./Hint/Hint.vue";
11
+ export { default as Icon } from "./Icon/Icon.vue";
12
+ export type { IconSize } from "./Icon/Icon.vue";
13
+ export { registerIcons, hasIcon } from "./Icon/registry";
14
+ export type { IconRegistration, IconVariants } from "./Icon/registry";
15
+ export { default as LightDarkToggle } from "./LightDarkToggle/LightDarkToggle.vue";
16
+ export { default as MultiSelect } from "./MultiSelect/MultiSelect.vue";
17
+ export type { MultiSelectOption } from "./MultiSelect/MultiSelect.vue";
18
+ export { default as NumberInput } from "./NumberInput/NumberInput.vue";
19
+ export type { NumberRange } from "./NumberInput/NumberInput.vue";
20
+ export { default as ParamEditor } from "./ParamEditor/ParamEditor.vue";
21
+ export type {
22
+ ParamEditorFormat,
23
+ ParamEditorValue,
24
+ } from "./ParamEditor/ParamEditor.vue";
25
+ export { default as SelectBox } from "./SelectBox/SelectBox.vue";
26
+ export type { SelectOption } from "./SelectBox/SelectBox.vue";
27
+ export { default as SidebarLayout } from "./SidebarLayout/SidebarLayout.vue";
28
+ export type { Tab } from "./SidebarLayout/SidebarLayout.vue";
29
+ export { default as Spinner } from "./Spinner/Spinner.vue";
30
+ export { default as TextInput } from "./TextInput/TextInput.vue";
31
+ export { default as Toggle } from "./Toggle/Toggle.vue";
32
+ export { default as ToggleGroup } from "./ToggleGroup/ToggleGroup.vue";
33
+ export type { ToggleGroupOption } from "./ToggleGroup/ToggleGroup.vue";
package/src/svg.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ declare module "*.svg?component" {
2
+ import type { DefineComponent } from "vue";
3
+ const component: DefineComponent;
4
+ export default component;
5
+ }