@rokkit/forms 1.0.0-next.122

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 (84) hide show
  1. package/dist/src/forms-old/input/types.d.ts +7 -0
  2. package/dist/src/forms-old/lib/form.d.ts +95 -0
  3. package/dist/src/forms-old/lib/index.d.ts +1 -0
  4. package/dist/src/index.d.ts +5 -0
  5. package/dist/src/input/index.d.ts +18 -0
  6. package/dist/src/lib/builder.svelte.d.ts +140 -0
  7. package/dist/src/lib/deprecated/nested.d.ts +48 -0
  8. package/dist/src/lib/deprecated/nested.spec.d.ts +1 -0
  9. package/dist/src/lib/deprecated/validator.d.ts +30 -0
  10. package/dist/src/lib/deprecated/validator.spec.d.ts +1 -0
  11. package/dist/src/lib/fields.d.ts +16 -0
  12. package/dist/src/lib/fields.spec.d.ts +1 -0
  13. package/dist/src/lib/index.d.ts +7 -0
  14. package/dist/src/lib/layout.d.ts +7 -0
  15. package/dist/src/lib/schema.d.ts +7 -0
  16. package/dist/src/lib/validation.d.ts +41 -0
  17. package/dist/src/types.d.ts +5 -0
  18. package/package.json +38 -0
  19. package/src/DataEditor.svelte +30 -0
  20. package/src/FieldLayout.svelte +48 -0
  21. package/src/FormRenderer.svelte +118 -0
  22. package/src/Input.svelte +75 -0
  23. package/src/InputField.svelte +55 -0
  24. package/src/ListEditor.svelte +44 -0
  25. package/src/NestedEditor.svelte +85 -0
  26. package/src/forms-old/CheckBox.svelte +56 -0
  27. package/src/forms-old/DataEditor.svelte +30 -0
  28. package/src/forms-old/FieldLayout.svelte +48 -0
  29. package/src/forms-old/Form.svelte +17 -0
  30. package/src/forms-old/Icon.svelte +76 -0
  31. package/src/forms-old/Item.svelte +25 -0
  32. package/src/forms-old/ListEditor.svelte +44 -0
  33. package/src/forms-old/Tabs.svelte +57 -0
  34. package/src/forms-old/Wrapper.svelte +12 -0
  35. package/src/forms-old/input/Input.svelte +17 -0
  36. package/src/forms-old/input/InputField.svelte +70 -0
  37. package/src/forms-old/input/InputSelect.svelte +23 -0
  38. package/src/forms-old/input/InputSwitch.svelte +19 -0
  39. package/src/forms-old/input/types.js +29 -0
  40. package/src/forms-old/lib/form.js +72 -0
  41. package/src/forms-old/lib/index.js +12 -0
  42. package/src/forms-old/mocks/CustomField.svelte +7 -0
  43. package/src/forms-old/mocks/CustomWrapper.svelte +8 -0
  44. package/src/forms-old/mocks/Register.svelte +25 -0
  45. package/src/index.js +7 -0
  46. package/src/inp/Input.svelte +17 -0
  47. package/src/inp/InputField.svelte +69 -0
  48. package/src/inp/InputSelect.svelte +23 -0
  49. package/src/inp/InputSwitch.svelte +19 -0
  50. package/src/input/InputCheckbox.svelte +74 -0
  51. package/src/input/InputColor.svelte +42 -0
  52. package/src/input/InputDate.svelte +54 -0
  53. package/src/input/InputDateTime.svelte +54 -0
  54. package/src/input/InputEmail.svelte +63 -0
  55. package/src/input/InputFile.svelte +45 -0
  56. package/src/input/InputMonth.svelte +54 -0
  57. package/src/input/InputNumber.svelte +57 -0
  58. package/src/input/InputPassword.svelte +60 -0
  59. package/src/input/InputRadio.svelte +60 -0
  60. package/src/input/InputRange.svelte +51 -0
  61. package/src/input/InputSelect.svelte +71 -0
  62. package/src/input/InputSwitch.svelte +29 -0
  63. package/src/input/InputTel.svelte +60 -0
  64. package/src/input/InputText.svelte +60 -0
  65. package/src/input/InputTextArea.svelte +59 -0
  66. package/src/input/InputTime.svelte +54 -0
  67. package/src/input/InputUrl.svelte +60 -0
  68. package/src/input/InputWeek.svelte +54 -0
  69. package/src/input/index.js +23 -0
  70. package/src/lib/Input.svelte +291 -0
  71. package/src/lib/builder.svelte.js +359 -0
  72. package/src/lib/deprecated/Form.svelte +17 -0
  73. package/src/lib/deprecated/FormRenderer.svelte +121 -0
  74. package/src/lib/deprecated/nested.js +192 -0
  75. package/src/lib/deprecated/nested.spec.js +512 -0
  76. package/src/lib/deprecated/validator.js +137 -0
  77. package/src/lib/deprecated/validator.spec.js +348 -0
  78. package/src/lib/fields.js +119 -0
  79. package/src/lib/fields.spec.js +250 -0
  80. package/src/lib/index.js +7 -0
  81. package/src/lib/layout.js +63 -0
  82. package/src/lib/schema.js +32 -0
  83. package/src/lib/validation.js +273 -0
  84. package/src/types.js +29 -0
@@ -0,0 +1,57 @@
1
+ <script>
2
+ import { Tabs } from 'bits-ui'
3
+
4
+ /**
5
+ * @typedef {Object} TabGroupProps
6
+ * @property {string} [class] - Additional CSS class names
7
+ * @property {any[]} [options] Array of options to display
8
+ * @property {FieldMapping} [fields] - Field mappings for extracting data
9
+ * @property {any} [value] - Selected value (bindable)
10
+ * @property {number} [tabindex] - Tabindex for keyboard navigation
11
+ * @property {import('svelte').Snippet} [child] - Snippet for rendering individual items
12
+ * @property {import('svelte').Snippet} [children] Snippet for rendering content
13
+ * @property {Function} [onselect] - Callback when item is selected
14
+ */
15
+ /** @type TabGroupProps */
16
+ let { options = [], value = $bindable(), fields, child, children, onchange } = $props()
17
+
18
+ // let selectedGroup = options.find
19
+ let tabOptions = $derived(options.map((option) => new Proxy(option, fields)))
20
+ let initialValue = $state()
21
+ let activeOption = $state()
22
+ let childSnippet = $derived(child ?? defaultChild)
23
+
24
+ $effect.pre(() => {
25
+ activeOption = tabOptions.find((proxy) => equals(proxy.value, value))
26
+ if (activeOption) initialValue = activeOption.id
27
+ })
28
+
29
+ function handleChange() {
30
+ activeOption = tabOptions.find((proxy) => equals(proxy.id, initialValue))
31
+ value = activeOption?.value
32
+ onchange?.(value)
33
+ // value = data
34
+ // onSelect?.(data)
35
+ }
36
+ </script>
37
+
38
+ {#snippet defaultChild(item)}
39
+ {item.get('text')}
40
+ {/snippet}
41
+
42
+ <Tabs.Root onValueChange={handleChange} bind:value={initialValue}>
43
+ <Tabs.List>
44
+ {#each tabOptions as tab (tab.id)}
45
+ <Tabs.Trigger value={tab.id}>
46
+ {@render childSnippet(tab)}
47
+ </Tabs.Trigger>
48
+ {/each}
49
+ </Tabs.List>
50
+
51
+ <!-- {#each tabOptions as tab (tab.id)} -->
52
+ <Tabs.Content>
53
+ {@render children()}
54
+ <!-- <ComparisonCharts {logs} groupBy={tab.value} {m} /> -->
55
+ </Tabs.Content>
56
+ <!-- {/each} -->
57
+ </Tabs.Root>
@@ -0,0 +1,12 @@
1
+ <script>
2
+ let { class: className = '', type = 'vertical', title = '', children } = $props()
3
+ </script>
4
+
5
+ <field-layout
6
+ class={className}
7
+ class:vertical={type === 'vertical'}
8
+ class:horizontal={type === 'horizontal'}
9
+ aria-label={title}
10
+ >
11
+ {@render children?.()}
12
+ </field-layout>
@@ -0,0 +1,17 @@
1
+ <script>
2
+ import { getContext } from 'svelte'
3
+ import { types } from './types'
4
+
5
+ const registry = getContext('registry')
6
+
7
+ let { value, type = 'text', using = {}, onchange, onfocus, onblur, ...restProps } = $props()
8
+
9
+ using = { ...types, ...using, ...registry?.editors }
10
+ let Template = using[type]
11
+ </script>
12
+
13
+ {#if type in using}
14
+ <Template bind:value {...restProps} {onchange} {onfocus} {onblur} />
15
+ {:else}
16
+ <error>Type "{type}" is not supported by Input</error>
17
+ {/if}
@@ -0,0 +1,70 @@
1
+ <script>
2
+ import { getContext } from 'svelte'
3
+ import { pick, omit } from 'ramda'
4
+ import Icon from '../Icon.svelte'
5
+ import Input from './Input.svelte'
6
+ import { types } from './types'
7
+
8
+ const registry = getContext('registry')
9
+
10
+ let {
11
+ class: className,
12
+ name,
13
+ value,
14
+ type,
15
+ required,
16
+ status,
17
+ disabled,
18
+ message,
19
+ using,
20
+ nolabel,
21
+ icon,
22
+ label,
23
+ description,
24
+ onchange,
25
+ ...restProps
26
+ } = $props()
27
+
28
+ using = { ...types, ...registry, ...using }
29
+ let pass = status === 'pass'
30
+ let fail = status === 'fail'
31
+ let warn = status === 'warn'
32
+ let rootProps = pick(['id'], restProps)
33
+ let properties = {
34
+ required,
35
+ readOnly: disabled,
36
+ ...omit(['id'], restProps),
37
+ name
38
+ }
39
+ </script>
40
+
41
+ <input-field
42
+ {...rootProps}
43
+ class="flex flex-col input-{type} {className} "
44
+ class:disabled
45
+ class:pass
46
+ class:fail
47
+ class:warn
48
+ class:empty={!value}
49
+ >
50
+ {#if label && !nolabel && !['switch', 'checkbox'].includes(type)}
51
+ <label for={name} class:required>
52
+ {label}
53
+ </label>
54
+ {/if}
55
+ <field class="flex w-full flex-row items-center" aria-label={description ?? label ?? name}>
56
+ {#if icon}
57
+ <Icon name={icon} />
58
+ {/if}
59
+ {#if type === 'switch'}
60
+ <label for={name} class:required>{label}</label>
61
+ {/if}
62
+ <Input id={name} bind:value {type} {...properties} {using} {onchange} />
63
+ {#if type === 'checkbox'}
64
+ <label for={name} class:required>{label}</label>
65
+ {/if}
66
+ </field>
67
+ {#if message}
68
+ <message class={status}>{message}</message>
69
+ {/if}
70
+ </input-field>
@@ -0,0 +1,23 @@
1
+ <script>
2
+ import { getValue, defaultFields } from '@rokkit/core'
3
+ import Select from '../Select.svelte'
4
+
5
+ let { name, value, options = [], fields, onchange, ...restProps } = $props()
6
+
7
+ let selected = $state()
8
+ let configFields = $derived({ ...defaultFields, ...fields })
9
+
10
+ function handle(data) {
11
+ value = getValue(data.value, configFields)
12
+ onchange?.(data)
13
+ }
14
+
15
+ $effect(() => {
16
+ if (value !== getValue(selected, configFields)) {
17
+ selected = options.find((option) => getValue(option, configFields) === value)
18
+ }
19
+ })
20
+ </script>
21
+
22
+ <input {name} type="hidden" bind:value />
23
+ <Select name="" value={selected} {options} {fields} {...restProps} onchange={handle} />
@@ -0,0 +1,19 @@
1
+ <script>
2
+ import { getValue, defaultFields } from '@rokkit/core'
3
+ import Switch from '../Switch.svelte'
4
+
5
+ let { name, value, options, fields, onchange, ...restProps } = $props()
6
+ // let selected = $state(null)
7
+ let configFields = $derived({ ...defaultFields, ...fields })
8
+ function handle(data) {
9
+ value = getValue(data.value, configFields)
10
+ onchange?.(data.value)
11
+ }
12
+ let selected = $derived(options.find((option) => getValue(option, configFields) === value))
13
+ // $effect(() => {
14
+ // selected = options.find((option) => getValue(option, configFields) === value)
15
+ // })
16
+ </script>
17
+
18
+ <input {name} type="hidden" bind:value />
19
+ <Switch bind:value={selected} {options} {fields} {...restProps} onchange={handle} />
@@ -0,0 +1,29 @@
1
+ import { toHyphenCase } from '@rokkit/core'
2
+ // skipcq: JS-C1003 - Importing all components from atoms
3
+ import * as NativeInput from '@rokkit/forms'
4
+ // skipcq: JS-C1003 - Importing all components from molecules
5
+ import CheckBox from '../CheckBox.svelte'
6
+
7
+ // import InputSelect from './InputSelect.svelte'
8
+ // import InputSwitch from './InputSwitch.svelte'
9
+
10
+ function extractComponentMap(components, prefix = /^Input/) {
11
+ return Object.entries(components).reduce(
12
+ (acc, [name, component]) => ({
13
+ ...acc,
14
+ [toHyphenCase(name.replace(prefix, ''))]: component
15
+ }),
16
+ {}
17
+ )
18
+ }
19
+ const native = extractComponentMap(NativeInput)
20
+
21
+ export const types = {
22
+ string: NativeInput.InputText,
23
+ integer: NativeInput.InputNumber,
24
+ boolean: CheckBox,
25
+ // enum: InputSelect,
26
+ phone: NativeInput.InputTel,
27
+ ...native
28
+ // ...extractComponentMap({ InputSelect, InputSwitch })
29
+ }
@@ -0,0 +1,72 @@
1
+ export const messages = {
2
+ required: '{name} is required',
3
+ email: '{name} should be a valid email address',
4
+ url: '{name} should be a valid URL',
5
+ color: '{name} should be a valid color',
6
+ number: '{name} should be a valid number',
7
+ min: '{name} should be greater than or equal to {min}',
8
+ max: '{name} should be less than or equal to {max}',
9
+ pattern: '{name} should match the pattern {pattern}',
10
+ exclusiveMin: '{name} should be greater than {min}',
11
+ exclusiveMax: '{name} should be less than {max}',
12
+ minLength: '{name} should be at least {minLength} characters',
13
+ maxLength: '{name} should be at most {maxLength} characters',
14
+ minItems: '{name} should have at least {minItems} items',
15
+ maxItems: '{name} should have at most {maxItems} items',
16
+ uniqueItems: '{name} should have unique items',
17
+ contains: '{name} should contain {contains}',
18
+ exclude: '{name} should not contain {exclude}',
19
+ integer: '{name} should be an integer'
20
+ }
21
+
22
+ export const dataTypes = {
23
+ integer: {
24
+ editor: 'inputText',
25
+ props: { type: 'number', step: 1 },
26
+ availableProps: ['min', 'max']
27
+ },
28
+ number: {
29
+ editor: 'inputText',
30
+ props: { type: 'number', step: 0.01 },
31
+ availableProps: ['min', 'max']
32
+ },
33
+ range: {
34
+ editor: 'inputRange',
35
+ props: { type: 'range' }
36
+ },
37
+
38
+ string: {
39
+ default: 'inputText',
40
+ text: 'inputText',
41
+ password: 'inputPassword',
42
+ email: 'inputEmail',
43
+ url: 'inputUrl',
44
+ tel: 'inputTel',
45
+ date: 'inputDate',
46
+ 'datetime-local': 'inputDateTimeLocal',
47
+ time: 'inputTime',
48
+ week: 'inputWeek',
49
+ month: 'inputMonth',
50
+ file: 'inputFile',
51
+ hidden: 'inputHidden',
52
+ color: 'inputColor',
53
+ colorpicker: 'inputColorPicker'
54
+ },
55
+ enum: {
56
+ default: 'inputSelect',
57
+ select: 'inputSelect',
58
+ radio: 'inputRadio'
59
+ },
60
+ boolean: {
61
+ default: 'inputCheckbox',
62
+ checkbox: 'inputCheckbox',
63
+ switch: 'inputSwitch',
64
+ radio: 'inputRadio'
65
+ },
66
+ array: {
67
+ default: 'inputArray'
68
+ },
69
+ object: {
70
+ default: 'inputObject'
71
+ }
72
+ }
@@ -0,0 +1,12 @@
1
+ export { messages, dataTypes } from './form'
2
+ export { deriveSchemaFromValue } from './schema'
3
+ export { deriveLayoutFromValue } from './layout'
4
+ export { getSchemaWithLayout, findAttributeByPath } from './fields'
5
+ export {
6
+ deriveNestedSchema,
7
+ flattenAttributes,
8
+ flattenObject,
9
+ flattenElement,
10
+ generateIndex,
11
+ generateTreeTable
12
+ } from './nested'
@@ -0,0 +1,7 @@
1
+ <script>
2
+ let { value, name, label, type, ...extraProps } = $props()
3
+ </script>
4
+
5
+ <h1>{type}:{label}</h1>
6
+ <p>{name}:{JSON.stringify(value)}</p>
7
+ <p>{JSON.stringify(Object.keys(extraProps))}</p>
@@ -0,0 +1,8 @@
1
+ <script>
2
+ let { title, type, children } = $props()
3
+ </script>
4
+
5
+ <field-layout class={type}>
6
+ <h1>{title}</h1>
7
+ {@render children?.()}
8
+ </field-layout>
@@ -0,0 +1,25 @@
1
+ <script>
2
+ import { setContext } from 'svelte'
3
+ // import { writable } from 'svelte/store'
4
+ import Wrapper from '..//Wrapper.svelte'
5
+ import Item from '../Item.svelte'
6
+ import Tabs from '../Tabs.svelte'
7
+ const registry = $state({})
8
+ setContext('registry', registry)
9
+
10
+ let { Template, using, properties } = $props()
11
+
12
+ using = {
13
+ editors: {},
14
+ components: {},
15
+ wrappers: {},
16
+ navigators: {},
17
+ ...using
18
+ }
19
+ registry.editors = { ...using.editors }
20
+ registry.components = { default: Item, ...using.components }
21
+ registry.wrappers = { default: Wrapper, ...using.wrappers }
22
+ registry.navigators = { default: Tabs, ...using.navigators }
23
+ </script>
24
+
25
+ <Template {...properties} />
package/src/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { FormBuilder } from './lib/builder.svelte.js'
2
+ // Enhanced Input Components
3
+ export { default as FormRenderer } from './FormRenderer.svelte'
4
+ export { default as Input } from './Input.svelte'
5
+ export { default as InputField } from './InputField.svelte'
6
+
7
+ export * from './input'
@@ -0,0 +1,17 @@
1
+ <script>
2
+ import { getContext } from 'svelte'
3
+ import { types } from './types'
4
+
5
+ const registry = getContext('registry')
6
+
7
+ let { value, type = 'text', using = {}, ...restProps } = $props()
8
+
9
+ using = { ...types, ...using, ...registry?.editors }
10
+ let Template = using[type]
11
+ </script>
12
+
13
+ {#if type in using}
14
+ <Template bind:value {...restProps} on:change on:focus on:blur />
15
+ {:else}
16
+ <error>Type "{type}" is not supported by Input</error>
17
+ {/if}
@@ -0,0 +1,69 @@
1
+ <script>
2
+ import { getContext } from 'svelte'
3
+ import { pick, omit } from 'ramda'
4
+ import Icon from '../Icon.svelte'
5
+ import Input from './Input.svelte'
6
+ import { types } from './types'
7
+
8
+ const registry = getContext('registry')
9
+
10
+ let {
11
+ class: className,
12
+ name,
13
+ value,
14
+ type,
15
+ required,
16
+ status,
17
+ disabled,
18
+ message,
19
+ using,
20
+ nolabel,
21
+ icon,
22
+ label,
23
+ description,
24
+ ...restProps
25
+ } = $props()
26
+
27
+ using = { ...types, ...registry, ...using }
28
+ let pass = status === 'pass'
29
+ let fail = status === 'fail'
30
+ let warn = status === 'warn'
31
+ let rootProps = pick(['id'], restProps)
32
+ let properties = {
33
+ required,
34
+ readOnly: disabled,
35
+ ...omit(['id'], restProps),
36
+ name
37
+ }
38
+ </script>
39
+
40
+ <input-field
41
+ {...rootProps}
42
+ class="flex flex-col input-{type} {className} "
43
+ class:disabled
44
+ class:pass
45
+ class:fail
46
+ class:warn
47
+ class:empty={!value}
48
+ >
49
+ {#if label && !nolabel && !['switch', 'checkbox'].includes(type)}
50
+ <label for={name} class:required>
51
+ {label}
52
+ </label>
53
+ {/if}
54
+ <field class="flex w-full flex-row items-center" aria-label={description ?? label ?? name}>
55
+ {#if icon}
56
+ <Icon name={icon} />
57
+ {/if}
58
+ {#if type === 'switch'}
59
+ <label for={name} class:required>{label}</label>
60
+ {/if}
61
+ <Input id={name} bind:value {type} {...properties} {using} on:change />
62
+ {#if type === 'checkbox'}
63
+ <label for={name} class:required>{label}</label>
64
+ {/if}
65
+ </field>
66
+ {#if message}
67
+ <message class={status}>{message}</message>
68
+ {/if}
69
+ </input-field>
@@ -0,0 +1,23 @@
1
+ <script>
2
+ import { getValue, defaultFields } from '@rokkit/core'
3
+ import Select from '../Select.svelte'
4
+
5
+ let { name, value, options = [], fields, onchange, ...restProps } = $props()
6
+
7
+ let selected = $state()
8
+ let configFields = $derived({ ...defaultFields, ...fields })
9
+
10
+ function handle(data) {
11
+ value = getValue(data.value, configFields)
12
+ onchange?.(data)
13
+ }
14
+
15
+ $effect(() => {
16
+ if (value !== getValue(selected, configFields)) {
17
+ selected = options.find((option) => getValue(option, configFields) === value)
18
+ }
19
+ })
20
+ </script>
21
+
22
+ <input {name} type="hidden" bind:value />
23
+ <Select name="" value={selected} {options} {fields} {...restProps} onchange={handle} />
@@ -0,0 +1,19 @@
1
+ <script>
2
+ import { getValue, defaultFields } from '@rokkit/core'
3
+ import Switch from '../Switch.svelte'
4
+
5
+ let { name, value, options, fields, ...restProps } = $props()
6
+ // let selected = $state(null)
7
+ let configFields = $derived({ ...defaultFields, ...fields })
8
+ function handle(data) {
9
+ value = getValue(data.value, configFields)
10
+ dispatch('change', data.value)
11
+ }
12
+ let selected = $derived(options.find((option) => getValue(option, configFields) === value))
13
+ // $effect(() => {
14
+ // selected = options.find((option) => getValue(option, configFields) === value)
15
+ // })
16
+ </script>
17
+
18
+ <input {name} type="hidden" bind:value />
19
+ <Switch bind:value={selected} {options} {fields} {...restProps} onchange={handle} />
@@ -0,0 +1,74 @@
1
+ <script>
2
+ import { Icon } from '@rokkit/ui'
3
+ import { defaultStateIcons } from '@rokkit/core'
4
+ import { isNil } from 'ramda'
5
+
6
+ /**
7
+ * @typedef {ObjectIcon} StateIcons
8
+ * @property {string} checked
9
+ * @property {string} unchecked
10
+ * @property {string} unknown
11
+ */
12
+
13
+ /**
14
+ * @typedef {Object} InputCheckboxProps
15
+ * @property {null|Boolean} value
16
+ * @property {'default'|'custom'} variant -
17
+ * @property {StateIcons} icons
18
+ * @property {Function} onchange
19
+ * @property {Function} onfocus
20
+ * @property {Function} onblur
21
+ * @property {boolean} required
22
+ * @property {boolean} disabled
23
+ * @property {string} name
24
+ * @property {string} id
25
+ */
26
+
27
+ /** @type {InputCheckboxProps & { [key: string]: any }} */
28
+ let {
29
+ value = $bindable(),
30
+ variant = 'default',
31
+ icons,
32
+ onchange,
33
+ onfocus,
34
+ onblur,
35
+ required,
36
+ disabled,
37
+ name,
38
+ id,
39
+ ...rest
40
+ } = $props()
41
+
42
+ function handleChange(event) {
43
+ value = Boolean(event.target.checked)
44
+ onchange?.(value)
45
+ }
46
+
47
+ function toggle() {
48
+ value = !Boolean(value)
49
+ onchange?.(value)
50
+ }
51
+
52
+ let checked = $derived(Boolean(value))
53
+ let stateIcons = $derived({ ...defaultStateIcons.checkbox, ...icons })
54
+ let icon = $derived(stateIcons[isNil(value) ? 'unknown' : value ? 'checked' : 'unchecked'])
55
+ </script>
56
+
57
+ <div data-checkbox-root data-variant={variant}>
58
+ <input
59
+ type="checkbox"
60
+ hidden={variant !== 'default'}
61
+ {required}
62
+ {disabled}
63
+ {name}
64
+ {id}
65
+ {checked}
66
+ onchange={handleChange}
67
+ {onfocus}
68
+ {onblur}
69
+ {...rest}
70
+ />
71
+ {#if variant !== 'default'}
72
+ <Icon name={icon} data-checkbox-icon role="button" onclick={toggle} />
73
+ {/if}
74
+ </div>
@@ -0,0 +1,42 @@
1
+ <script>
2
+ /**
3
+ * @typedef {Object} InputColorProps
4
+ * @property {string} value
5
+ * @property {Function} onchange
6
+ * @property {Function} onfocus
7
+ * @property {Function} onblur
8
+ * @property {boolean} required
9
+ * @property {boolean} disabled
10
+ * @property {string} name
11
+ * @property {string} id
12
+ * @property {string} autocomplete
13
+ */
14
+
15
+ /** @type {InputColorProps & { [key: string]: any }} */
16
+ let {
17
+ value = $bindable(),
18
+ onchange,
19
+ onfocus,
20
+ onblur,
21
+ required,
22
+ disabled,
23
+ name,
24
+ id,
25
+ autocomplete,
26
+ ...rest
27
+ } = $props()
28
+ </script>
29
+
30
+ <input
31
+ bind:value
32
+ type="color"
33
+ {required}
34
+ {disabled}
35
+ {name}
36
+ {id}
37
+ {autocomplete}
38
+ {onchange}
39
+ {onfocus}
40
+ {onblur}
41
+ {...rest}
42
+ />
@@ -0,0 +1,54 @@
1
+ <script>
2
+ /**
3
+ * @typedef {Object} InputDateProps
4
+ * @property {string} value
5
+ * @property {Function} onchange
6
+ * @property {Function} onfocus
7
+ * @property {Function} onblur
8
+ * @property {string} min
9
+ * @property {string} max
10
+ * @property {number} step
11
+ * @property {boolean} required
12
+ * @property {boolean} disabled
13
+ * @property {boolean} readonly
14
+ * @property {string} name
15
+ * @property {string} id
16
+ * @property {string} autocomplete
17
+ */
18
+
19
+ /** @type {InputDateProps & { [key: string]: any }} */
20
+ let {
21
+ value = $bindable(),
22
+ onchange,
23
+ onfocus,
24
+ onblur,
25
+ min,
26
+ max,
27
+ step,
28
+ required,
29
+ disabled,
30
+ readonly,
31
+ name,
32
+ id,
33
+ autocomplete,
34
+ ...rest
35
+ } = $props()
36
+ </script>
37
+
38
+ <input
39
+ bind:value
40
+ type="date"
41
+ {min}
42
+ {max}
43
+ {step}
44
+ {required}
45
+ {disabled}
46
+ {readonly}
47
+ {name}
48
+ {id}
49
+ {autocomplete}
50
+ {onchange}
51
+ {onfocus}
52
+ {onblur}
53
+ {...rest}
54
+ />