@balikjs/mobile 0.0.1

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 (104) hide show
  1. package/README.md +33 -0
  2. package/dist/mobile.js +3062 -0
  3. package/dist/styles.css +1 -0
  4. package/package.json +49 -0
  5. package/src/Alert/Alert.jsx +67 -0
  6. package/src/Alert/Alert.module.css +87 -0
  7. package/src/Alert/index.js +1 -0
  8. package/src/Avatar/Avatar.jsx +77 -0
  9. package/src/Avatar/Avatar.module.css +74 -0
  10. package/src/Avatar/index.js +1 -0
  11. package/src/Badge/Badge.jsx +83 -0
  12. package/src/Badge/Badge.module.css +141 -0
  13. package/src/Badge/index.js +1 -0
  14. package/src/BottomNavigation/BottomNavigation.jsx +61 -0
  15. package/src/BottomNavigation/BottomNavigation.module.css +53 -0
  16. package/src/BottomNavigation/index.js +1 -0
  17. package/src/BottomSheet/BottomSheet.jsx +51 -0
  18. package/src/BottomSheet/BottomSheet.module.css +56 -0
  19. package/src/BottomSheet/index.js +1 -0
  20. package/src/Button/Button.jsx +77 -0
  21. package/src/Button/Button.module.css +124 -0
  22. package/src/Button/index.js +1 -0
  23. package/src/Card/Card.jsx +31 -0
  24. package/src/Card/Card.module.css +4 -0
  25. package/src/Card/index.js +1 -0
  26. package/src/Checkbox/Checkbox.jsx +64 -0
  27. package/src/Checkbox/Checkbox.module.css +146 -0
  28. package/src/Checkbox/index.js +1 -0
  29. package/src/Clipboard/Clipboard.jsx +82 -0
  30. package/src/Clipboard/Clipboard.module.css +126 -0
  31. package/src/Clipboard/index.js +1 -0
  32. package/src/CloseButton/CloseButton.jsx +51 -0
  33. package/src/CloseButton/CloseButton.module.css +94 -0
  34. package/src/Confirm/Confirm.jsx +52 -0
  35. package/src/Confirm/Confirm.module.css +5 -0
  36. package/src/Confirm/index.js +1 -0
  37. package/src/Dialog/Dialog.jsx +63 -0
  38. package/src/Dialog/Dialog.module.css +111 -0
  39. package/src/Dialog/index.js +1 -0
  40. package/src/Divider/Divider.jsx +38 -0
  41. package/src/Divider/Divider.module.css +16 -0
  42. package/src/Divider/index.js +1 -0
  43. package/src/Drawer/Drawer.jsx +55 -0
  44. package/src/Drawer/Drawer.module.css +68 -0
  45. package/src/Drawer/index.js +1 -0
  46. package/src/Empty/Empty.jsx +35 -0
  47. package/src/Empty/Empty.module.css +17 -0
  48. package/src/Empty/index.js +1 -0
  49. package/src/Fab/Fab.jsx +91 -0
  50. package/src/Fab/Fab.module.css +94 -0
  51. package/src/Fab/index.js +1 -0
  52. package/src/Input/Input.jsx +53 -0
  53. package/src/Input/Input.module.css +97 -0
  54. package/src/Input/index.js +1 -0
  55. package/src/Link/Link.jsx +31 -0
  56. package/src/Link/Link.module.css +18 -0
  57. package/src/Link/index.js +1 -0
  58. package/src/Popover/Popover.jsx +162 -0
  59. package/src/Popover/Popover.module.css +63 -0
  60. package/src/Popover/index.js +1 -0
  61. package/src/RadioGroup/Radio.jsx +52 -0
  62. package/src/RadioGroup/Radio.module.css +133 -0
  63. package/src/RadioGroup/RadioGroup.jsx +36 -0
  64. package/src/RadioGroup/RadioGroup.module.css +23 -0
  65. package/src/RadioGroup/index.js +2 -0
  66. package/src/SearchInput/SearchInput.jsx +89 -0
  67. package/src/SearchInput/SearchInput.module.css +169 -0
  68. package/src/SearchInput/index.js +1 -0
  69. package/src/Select/Select.jsx +101 -0
  70. package/src/Select/Select.module.css +174 -0
  71. package/src/Select/index.js +1 -0
  72. package/src/SelectPc/Select.jsx +88 -0
  73. package/src/SelectPc/SelectPc.module.css +132 -0
  74. package/src/SelectPc/index.js +1 -0
  75. package/src/Skeleton/Skeleton.jsx +55 -0
  76. package/src/Skeleton/Skeleton.module.css +33 -0
  77. package/src/Skeleton/index.js +1 -0
  78. package/src/Slider/Slider.jsx +50 -0
  79. package/src/Slider/Slider.module.css +77 -0
  80. package/src/Slider/index.js +1 -0
  81. package/src/Spinner/Spinner.jsx +45 -0
  82. package/src/Spinner/Spinner.module.css +35 -0
  83. package/src/Spinner/index.js +1 -0
  84. package/src/Switch/Switch.jsx +51 -0
  85. package/src/Switch/Switch.module.css +156 -0
  86. package/src/Switch/index.js +1 -0
  87. package/src/Tabs/Tabs.jsx +75 -0
  88. package/src/Tabs/Tabs.module.css +45 -0
  89. package/src/Tabs/index.js +1 -0
  90. package/src/Tag/Tag.jsx +74 -0
  91. package/src/Tag/Tag.module.css +128 -0
  92. package/src/Tag/index.js +1 -0
  93. package/src/Textarea/Textarea.jsx +52 -0
  94. package/src/Textarea/Textarea.module.css +89 -0
  95. package/src/Textarea/index.js +1 -0
  96. package/src/Toast/Toast.jsx +169 -0
  97. package/src/Toast/Toast.module.css +152 -0
  98. package/src/Toast/index.js +1 -0
  99. package/src/Tooltip/Tooltip.jsx +42 -0
  100. package/src/Tooltip/Tooltip.module.css +41 -0
  101. package/src/Tooltip/index.js +1 -0
  102. package/src/index.js +34 -0
  103. package/src/styles/index.css +90 -0
  104. package/src/styles/tokens.css +227 -0
@@ -0,0 +1,31 @@
1
+ import { splitProps, mergeProps } from 'solid-js'
2
+ import styles from './Link.module.css'
3
+
4
+ const DEFAULT_PROPS = {}
5
+
6
+ /**
7
+ * @param {import('solid-js').JSX.AnchorHTMLAttributes<HTMLAnchorElement> & {
8
+ * class?: string
9
+ * }} props
10
+ */
11
+ export function Link(props) {
12
+ const [local, rest] = splitProps(
13
+ mergeProps(DEFAULT_PROPS, props),
14
+ ['class', 'children'],
15
+ )
16
+
17
+ return (
18
+ <a
19
+ {...rest}
20
+ class={[
21
+ 'balik-link',
22
+ styles.base,
23
+ local.class,
24
+ ]
25
+ .filter(Boolean)
26
+ .join(' ')}
27
+ >
28
+ {local.children}
29
+ </a>
30
+ )
31
+ }
@@ -0,0 +1,18 @@
1
+ .base {
2
+ color: var(--base-edge);
3
+ text-decoration: none;
4
+ cursor: pointer;
5
+ font-weight: 500;
6
+ transition: color var(--b-transition-fast), text-decoration-color var(--b-transition-fast);
7
+ }
8
+
9
+ .base:hover {
10
+ text-decoration: underline;
11
+ text-decoration-color: color-mix(in oklch, var(--base-edge) 60%, transparent);
12
+ }
13
+
14
+ .base:focus-visible {
15
+ outline: 2px solid var(--color-focus-border);
16
+ outline-offset: 2px;
17
+ border-radius: 2px;
18
+ }
@@ -0,0 +1 @@
1
+ export { Link } from './Link.jsx'
@@ -0,0 +1,162 @@
1
+ import { splitProps, mergeProps } from 'solid-js'
2
+ import { Portal } from 'solid-js/web'
3
+ import { Popover as ArkPopover } from '@ark-ui/solid'
4
+ import styles from './Popover.module.css'
5
+
6
+ /**
7
+ * @param {import('@ark-ui/solid').PopoverRootProps & {
8
+ * class?: string
9
+ * }} props
10
+ */
11
+ function PopoverRoot(props) {
12
+ const [local, rest] = splitProps(
13
+ mergeProps({}, props),
14
+ ['class', 'children'],
15
+ )
16
+
17
+ return (
18
+ <ArkPopover.Root {...rest} lazyMount unmountOnExit>
19
+ {local.children}
20
+ </ArkPopover.Root>
21
+ )
22
+ }
23
+
24
+ /**
25
+ * @param {import('@ark-ui/solid').PopoverTriggerProps & {
26
+ * class?: string
27
+ * }} props
28
+ */
29
+ function PopoverTrigger(props) {
30
+ const [local, rest] = splitProps(
31
+ mergeProps({}, props),
32
+ ['class', 'children'],
33
+ )
34
+
35
+ return (
36
+ <ArkPopover.Trigger
37
+ {...rest}
38
+ as="div"
39
+ class={[
40
+ 'balik-popover-trigger',
41
+ local.class,
42
+ ].filter(Boolean).join(' ')}
43
+ >
44
+ {local.children}
45
+ </ArkPopover.Trigger>
46
+ )
47
+ }
48
+
49
+ /**
50
+ * @param {import('@ark-ui/solid').PopoverContentProps & {
51
+ * class?: string
52
+ * }} props
53
+ */
54
+ function PopoverContent(props) {
55
+ const [local, rest] = splitProps(
56
+ mergeProps({}, props),
57
+ ['class', 'children'],
58
+ )
59
+
60
+ return (
61
+ <Portal mount={document.body}>
62
+ <ArkPopover.Positioner class={styles.positioner}>
63
+ <ArkPopover.Content
64
+ {...rest}
65
+ class={[
66
+ 'balik-popover-content',
67
+ styles.content,
68
+ local.class,
69
+ ].filter(Boolean).join(' ')}
70
+ >
71
+ <ArkPopover.Arrow class={styles.arrow}>
72
+ <ArkPopover.ArrowTip class={styles.arrowTip} />
73
+ </ArkPopover.Arrow>
74
+ {local.children}
75
+ </ArkPopover.Content>
76
+ </ArkPopover.Positioner>
77
+ </Portal>
78
+ )
79
+ }
80
+
81
+ /**
82
+ * @param {import('@ark-ui/solid').PopoverCloseTriggerProps & {
83
+ * class?: string
84
+ * }} props
85
+ */
86
+ function PopoverCloseTrigger(props) {
87
+ const [local, rest] = splitProps(
88
+ mergeProps({}, props),
89
+ ['class', 'children'],
90
+ )
91
+
92
+ return (
93
+ <ArkPopover.CloseTrigger
94
+ {...rest}
95
+ class={[
96
+ styles.closeTrigger,
97
+ local.class,
98
+ ].filter(Boolean).join(' ')}
99
+ >
100
+ {local.children}
101
+ </ArkPopover.CloseTrigger>
102
+ )
103
+ }
104
+
105
+ /**
106
+ * @param {import('@ark-ui/solid').PopoverTitleProps & {
107
+ * class?: string
108
+ * }} props
109
+ */
110
+ function PopoverTitle(props) {
111
+ const [local, rest] = splitProps(
112
+ mergeProps({}, props),
113
+ ['class', 'children'],
114
+ )
115
+
116
+ return (
117
+ <ArkPopover.Title
118
+ {...rest}
119
+ class={[
120
+ styles.title,
121
+ local.class,
122
+ ].filter(Boolean).join(' ')}
123
+ >
124
+ {local.children}
125
+ </ArkPopover.Title>
126
+ )
127
+ }
128
+
129
+ /**
130
+ * @param {import('@ark-ui/solid').PopoverDescriptionProps & {
131
+ * class?: string
132
+ * }} props
133
+ */
134
+ function PopoverDescription(props) {
135
+ const [local, rest] = splitProps(
136
+ mergeProps({}, props),
137
+ ['class', 'children'],
138
+ )
139
+
140
+ return (
141
+ <ArkPopover.Description
142
+ {...rest}
143
+ class={[
144
+ styles.description,
145
+ local.class,
146
+ ].filter(Boolean).join(' ')}
147
+ >
148
+ {local.children}
149
+ </ArkPopover.Description>
150
+ )
151
+ }
152
+
153
+ export function Popover(props) {
154
+ return <PopoverRoot {...props} />
155
+ }
156
+
157
+ Popover.Trigger = PopoverTrigger
158
+ Popover.Content = PopoverContent
159
+ Popover.Title = PopoverTitle
160
+ Popover.Description = PopoverDescription
161
+ Popover.CloseTrigger = PopoverCloseTrigger
162
+ Popover.Original = ArkPopover
@@ -0,0 +1,63 @@
1
+ .positioner {
2
+ z-index: var(--b-z-index-dropdown);
3
+ }
4
+
5
+ .content {
6
+ padding: 12px;
7
+ background-color: var(--base-bg);
8
+ border-radius: var(--b-radius-l2-md);
9
+ box-shadow: var(--b-shadow-lg);
10
+ border: 1px solid color-mix(in oklch, var(--base-fg) 8%, var(--base-bg));
11
+ outline: none;
12
+ animation: popoverIn 0.15s ease;
13
+ }
14
+
15
+ @keyframes popoverIn {
16
+ from {
17
+ opacity: 0;
18
+ transform: scale(0.95);
19
+ }
20
+ to {
21
+ opacity: 1;
22
+ transform: scale(1);
23
+ }
24
+ }
25
+
26
+ .arrowTip {
27
+ --arrow-size: 8px;
28
+ --arrow-background: var(--base-bg);
29
+ }
30
+
31
+ .closeTrigger {
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ position: absolute;
36
+ top: 8px;
37
+ right: 8px;
38
+ width: 24px;
39
+ height: 24px;
40
+ padding: 0;
41
+ border: none;
42
+ border-radius: var(--b-radius-l1-md);
43
+ background: transparent;
44
+ color: color-mix(in oklch, var(--base-fg) 40%, transparent);
45
+ cursor: pointer;
46
+ touch-action: manipulation;
47
+ }
48
+
49
+ .title {
50
+ margin: 0;
51
+ padding-right: 24px;
52
+ font-size: var(--b-comp-font-size-md);
53
+ font-weight: 600;
54
+ color: var(--base-fg);
55
+ }
56
+
57
+ .description {
58
+ margin: 0;
59
+ margin-top: 4px;
60
+ font-size: var(--b-comp-font-size-sm);
61
+ color: color-mix(in oklch, var(--base-fg) 55%, transparent);
62
+ line-height: 1.5;
63
+ }
@@ -0,0 +1 @@
1
+ export { Popover } from './Popover.jsx'
@@ -0,0 +1,52 @@
1
+ import { splitProps, mergeProps } from 'solid-js'
2
+ import { RadioGroup as ArkRadioGroup } from '@ark-ui/solid'
3
+ import styles from './Radio.module.css'
4
+
5
+ const sizes = {
6
+ xs: styles.sizeXs,
7
+ sm: styles.sizeSm,
8
+ md: styles.sizeMd,
9
+ lg: styles.sizeLg,
10
+ xl: styles.sizeXl,
11
+ '2xl': styles.size2xl,
12
+ }
13
+
14
+ /**
15
+ * @param {import('@ark-ui/solid').RadioGroupItemProps & {
16
+ * size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
17
+ * class?: string
18
+ * }} props
19
+ */
20
+ export function Radio(props) {
21
+ const [local, rest] = splitProps(
22
+ mergeProps({ size: 'md' }, props),
23
+ ['class', 'children', 'size'],
24
+ )
25
+
26
+ return (
27
+ <ArkRadioGroup.Item
28
+ {...rest}
29
+ class={[
30
+ 'balik-radio',
31
+ styles.item,
32
+ sizes[local.size],
33
+ local.class,
34
+ ]
35
+ .filter(Boolean)
36
+ .join(' ')}
37
+ >
38
+ <ArkRadioGroup.ItemControl class={styles.control} />
39
+ <ArkRadioGroup.ItemText class={styles.text}>
40
+ {local.children}
41
+ </ArkRadioGroup.ItemText>
42
+ <ArkRadioGroup.ItemHiddenInput />
43
+ </ArkRadioGroup.Item>
44
+ )
45
+ }
46
+
47
+ Radio.Original = {
48
+ Item: ArkRadioGroup.Item,
49
+ ItemControl: ArkRadioGroup.ItemControl,
50
+ ItemText: ArkRadioGroup.ItemText,
51
+ ItemHiddenInput: ArkRadioGroup.ItemHiddenInput,
52
+ }
@@ -0,0 +1,133 @@
1
+ .item {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ gap: var(--_ctrl-gap, 10px);
5
+ min-height: var(--_ctrl-min-height, var(--b-comp-height-md));
6
+ cursor: pointer;
7
+ font-family: inherit;
8
+ user-select: none;
9
+ touch-action: manipulation;
10
+ }
11
+
12
+ .item[data-disabled] {
13
+ cursor: not-allowed;
14
+ }
15
+
16
+ .control {
17
+ width: var(--_ctrl-size, var(--b-comp-secondary-height-md));
18
+ height: var(--_ctrl-size, var(--b-comp-secondary-height-md));
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+ flex-shrink: 0;
23
+ border-radius: 50%;
24
+ border: 1px solid var(--base-edge);
25
+ background-color: var(--base-bg);
26
+ transition: border-color var(--b-transition-fast);
27
+ }
28
+
29
+ .control::after {
30
+ content: '';
31
+ display: block;
32
+ width: var(--_ctrl-dot-size, calc(var(--b-comp-secondary-height-md) / 2));
33
+ height: var(--_ctrl-dot-size, calc(var(--b-comp-secondary-height-md) / 2));
34
+ border-radius: 50%;
35
+ background-color: var(--base-edge);
36
+ transform: scale(0);
37
+ transition: transform var(--b-transition-fast);
38
+ }
39
+
40
+ .control[data-state="checked"] {
41
+ border-color: var(--base-edge);
42
+ }
43
+
44
+ .control[data-state="checked"]::after {
45
+ transform: scale(1);
46
+ }
47
+
48
+ .item[data-disabled] .control {
49
+ border-color: var(--color-disabled-border);
50
+ background-color: var(--color-disabled-bg);
51
+ }
52
+
53
+ .item[data-disabled] .control[data-state="checked"]::after {
54
+ background-color: var(--color-disabled-fg);
55
+ }
56
+
57
+ .item[data-invalid] .control {
58
+ border-color: var(--color-danger);
59
+ }
60
+
61
+ .item[data-invalid] .control[data-state="checked"]::after {
62
+ background-color: var(--color-danger);
63
+ }
64
+
65
+ .control:active:not([data-disabled]) {
66
+ transform: scale(0.88);
67
+ }
68
+
69
+ .text {
70
+ font-size: var(--_ctrl-font-size, var(--b-comp-font-size-md));
71
+ line-height: var(--_ctrl-line-height, var(--b-comp-line-height-md));
72
+ color: var(--base-fg);
73
+ }
74
+
75
+ .item[data-disabled] .text {
76
+ color: var(--color-disabled-fg);
77
+ }
78
+
79
+ /* ─── Size Overrides ─── */
80
+
81
+ .sizeXs {
82
+ --_ctrl-size: var(--b-comp-secondary-height-xs);
83
+ --_ctrl-dot-size: calc(var(--b-comp-secondary-height-xs) / 2);
84
+ --_ctrl-gap: 8px;
85
+ --_ctrl-min-height: var(--b-comp-height-xs);
86
+ --_ctrl-font-size: var(--b-comp-font-size-xs);
87
+ --_ctrl-line-height: var(--b-comp-line-height-xs);
88
+ }
89
+
90
+ .sizeSm {
91
+ --_ctrl-size: var(--b-comp-secondary-height-sm);
92
+ --_ctrl-dot-size: calc(var(--b-comp-secondary-height-sm) / 2);
93
+ --_ctrl-gap: 9px;
94
+ --_ctrl-min-height: var(--b-comp-height-sm);
95
+ --_ctrl-font-size: var(--b-comp-font-size-sm);
96
+ --_ctrl-line-height: var(--b-comp-line-height-sm);
97
+ }
98
+
99
+ .sizeMd {
100
+ --_ctrl-size: var(--b-comp-secondary-height-md);
101
+ --_ctrl-dot-size: calc(var(--b-comp-secondary-height-md) / 2);
102
+ --_ctrl-gap: 10px;
103
+ --_ctrl-min-height: var(--b-comp-height-md);
104
+ --_ctrl-font-size: var(--b-comp-font-size-md);
105
+ --_ctrl-line-height: var(--b-comp-line-height-md);
106
+ }
107
+
108
+ .sizeLg {
109
+ --_ctrl-size: var(--b-comp-secondary-height-lg);
110
+ --_ctrl-dot-size: calc(var(--b-comp-secondary-height-lg) / 2);
111
+ --_ctrl-gap: 11px;
112
+ --_ctrl-min-height: var(--b-comp-height-lg);
113
+ --_ctrl-font-size: var(--b-comp-font-size-lg);
114
+ --_ctrl-line-height: var(--b-comp-line-height-lg);
115
+ }
116
+
117
+ .sizeXl {
118
+ --_ctrl-size: var(--b-comp-secondary-height-xl);
119
+ --_ctrl-dot-size: calc(var(--b-comp-secondary-height-xl) / 2);
120
+ --_ctrl-gap: 12px;
121
+ --_ctrl-min-height: var(--b-comp-height-xl);
122
+ --_ctrl-font-size: var(--b-comp-font-size-xl);
123
+ --_ctrl-line-height: var(--b-comp-line-height-xl);
124
+ }
125
+
126
+ .size2xl {
127
+ --_ctrl-size: var(--b-comp-secondary-height-2xl);
128
+ --_ctrl-dot-size: calc(var(--b-comp-secondary-height-2xl) / 2);
129
+ --_ctrl-gap: 16px;
130
+ --_ctrl-min-height: var(--b-comp-height-2xl);
131
+ --_ctrl-font-size: var(--b-comp-font-size-2xl);
132
+ --_ctrl-line-height: var(--b-comp-line-height-2xl);
133
+ }
@@ -0,0 +1,36 @@
1
+ import { splitProps, mergeProps } from 'solid-js'
2
+ import { RadioGroup as ArkRadioGroup } from '@ark-ui/solid'
3
+ import styles from './RadioGroup.module.css'
4
+
5
+ /**
6
+ * @param {import('@ark-ui/solid').RadioGroupRootProps & {
7
+ * label?: string
8
+ * class?: string
9
+ * }} props
10
+ */
11
+ export function RadioGroup(props) {
12
+ const [local, rest] = splitProps(
13
+ mergeProps({}, props),
14
+ ['label', 'class', 'children'],
15
+ )
16
+
17
+ return (
18
+ <ArkRadioGroup.Root
19
+ {...rest}
20
+ class={[
21
+ 'balik-radio-group',
22
+ styles.root,
23
+ local.class,
24
+ ]
25
+ .filter(Boolean)
26
+ .join(' ')}
27
+ >
28
+ {local.label && (
29
+ <ArkRadioGroup.Label class={styles.label}>
30
+ {local.label}
31
+ </ArkRadioGroup.Label>
32
+ )}
33
+ {local.children}
34
+ </ArkRadioGroup.Root>
35
+ )
36
+ }
@@ -0,0 +1,23 @@
1
+ .root {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 0;
5
+ }
6
+
7
+ .root[data-orientation="horizontal"] {
8
+ flex-direction: row;
9
+ gap: 20px;
10
+ }
11
+
12
+ .label {
13
+ font-size: var(--b-comp-font-size-sm);
14
+ font-weight: 600;
15
+ color: var(--base-fg);
16
+ margin-bottom: 8px;
17
+ }
18
+
19
+ .root[data-orientation="horizontal"] .label {
20
+ margin-bottom: 0;
21
+ align-self: center;
22
+ margin-inline-end: 4px;
23
+ }
@@ -0,0 +1,2 @@
1
+ export { RadioGroup } from './RadioGroup.jsx'
2
+ export { Radio } from './Radio.jsx'
@@ -0,0 +1,89 @@
1
+ import { splitProps, mergeProps, createSignal, onCleanup, on } from 'solid-js'
2
+ import { ark } from '@ark-ui/solid/factory'
3
+ import { Search } from 'lucide-solid'
4
+ import styles from './SearchInput.module.css'
5
+
6
+ const variants = {
7
+ solid: styles.solid,
8
+ outline: styles.outline,
9
+ singleline: styles.singleline,
10
+ }
11
+
12
+ const sizes = {
13
+ xs: styles.sizeXs,
14
+ sm: styles.sizeSm,
15
+ md: styles.sizeMd,
16
+ lg: styles.sizeLg,
17
+ xl: styles.sizeXl,
18
+ }
19
+
20
+ const DEFAULT_PROPS = {
21
+ variant: 'outline',
22
+ size: 'md',
23
+ disabled: false,
24
+ debounce: 300,
25
+ }
26
+
27
+ /**
28
+ * @param {import('solid-js').JSX.InputHTMLAttributes<HTMLInputElement> & {
29
+ * variant?: 'solid' | 'outline' | 'singleline'
30
+ * size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
31
+ * onKeywordChange?: (keyword: string) => void
32
+ * debounce?: number
33
+ * class?: string
34
+ * }} props
35
+ */
36
+ export function SearchInput(props) {
37
+ const [local, rest] = splitProps(
38
+ mergeProps(DEFAULT_PROPS, props),
39
+ ['variant', 'size', 'class', 'onKeywordChange', 'debounce', 'placeholder'],
40
+ )
41
+
42
+ const [keyword, setKeyword] = createSignal('')
43
+
44
+ on(keyword, (val) => {
45
+ const timer = setTimeout(() => {
46
+ local.onKeywordChange?.(val)
47
+ }, local.debounce)
48
+ onCleanup(() => clearTimeout(timer))
49
+ })
50
+
51
+ const handleInput = (e) => {
52
+ setKeyword(e.target.value)
53
+ }
54
+
55
+ return (
56
+ <div
57
+ class={[
58
+ 'balik-search-input',
59
+ `balik-search-input--${local.variant}`,
60
+ `balik-search-input--${local.size}`,
61
+ styles.base,
62
+ variants[local.variant],
63
+ sizes[local.size],
64
+ local.class,
65
+ ]
66
+ .filter(Boolean)
67
+ .join(' ')}
68
+ >
69
+ <Search
70
+ aria-hidden="true"
71
+ class={[
72
+ 'balik-search-input__icon',
73
+ styles.icon,
74
+ ].join(' ')}
75
+ />
76
+ <ark.input
77
+ {...rest}
78
+ type="search"
79
+ autocomplete="off"
80
+ placeholder={local.placeholder}
81
+ onInput={handleInput}
82
+ class={[
83
+ 'balik-search-input__input',
84
+ styles.input,
85
+ ].join(' ')}
86
+ />
87
+ </div>
88
+ )
89
+ }