@plastic-js/tsumiki 0.1.22 → 0.1.24
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.
- package/README.md +838 -65
- package/dist/components/Accordion.js +93 -4
- package/dist/components/Avatar.js +96 -4
- package/dist/components/BottomSheet.js +131 -0
- package/dist/components/Button.js +194 -0
- package/dist/components/CardNumberInput.js +28 -44
- package/dist/components/Carousel.js +71 -5
- package/dist/components/Checkbox.js +178 -4
- package/dist/components/Clipboard.js +135 -5
- package/dist/components/CloseButton.js +97 -0
- package/dist/components/Collapsible.js +22 -4
- package/dist/components/ColorPicker.js +327 -4
- package/dist/components/Combobox.js +86 -13
- package/dist/components/ConfirmDialog.js +174 -19
- package/dist/components/DateInput.js +437 -5
- package/dist/components/{DatePickerMobile/wheel.js → DateWheel.js} +1 -3
- package/dist/components/Dialog.js +214 -110
- package/dist/components/Drawer.js +169 -4
- package/dist/components/Field.js +121 -5
- package/dist/components/Fieldset.js +64 -5
- package/dist/components/FileUpload.js +181 -4
- package/dist/components/FocusTrap.js +0 -2
- package/dist/components/Icon.js +32 -17
- package/dist/components/Input.js +211 -0
- package/dist/components/Listbox.js +47 -4
- package/dist/components/Menu.js +99 -4
- package/dist/components/MoneyInput.js +33 -85
- package/dist/components/NumberInput.js +117 -4
- package/dist/components/Pagination.js +91 -5
- package/dist/components/Popover.js +123 -4
- package/dist/components/Portal.js +0 -2
- package/dist/components/Presence.js +0 -2
- package/dist/components/Progress.js +107 -4
- package/dist/components/RadioGroup.js +104 -4
- package/dist/components/RatingGroup.js +75 -4
- package/dist/components/SearchInput.js +60 -55
- package/dist/components/Select.js +428 -5
- package/dist/components/SelectPc.js +239 -0
- package/dist/components/SignaturePad.js +77 -4
- package/dist/components/Skeleton.js +2 -4
- package/dist/components/Slider.js +112 -4
- package/dist/components/Spinner.js +41 -0
- package/dist/components/Splitter.js +51 -4
- package/dist/components/Steps.js +259 -4
- package/dist/components/SwipeReveal.js +2 -4
- package/dist/components/Switch.js +147 -4
- package/dist/components/Tabs.js +80 -4
- package/dist/components/TagsInput.js +128 -4
- package/dist/components/Toast.js +174 -4
- package/dist/components/Toggle.js +39 -4
- package/dist/components/ToggleGroup.js +103 -4
- package/dist/components/Tour.js +63 -4
- package/dist/components/TreeView.js +113 -4
- package/dist/index.js +44 -45
- package/dist/tsumiki.css +1 -0
- package/docs/api.md +670 -0
- package/docs/component-api-pattern.md +362 -0
- package/package.json +16 -6
- package/src/styles/color.css +112 -0
- package/src/styles/index.css +1 -0
- package/src/styles/radius.css +27 -0
- package/src/styles/reset.css +111 -0
- package/src/styles/shadow.css +5 -0
- package/src/styles/sizing.css +59 -0
- package/src/styles/spacing.css +9 -0
- package/src/styles/theme.css +38 -0
- package/src/styles/tokens.css +22 -0
- package/src/styles/transition.css +5 -0
- package/src/styles/typography.css +8 -0
- package/dist/components/Accordion.js.map +0 -1
- package/dist/components/Avatar.js.map +0 -1
- package/dist/components/CardNumberInput.js.map +0 -1
- package/dist/components/Carousel.js.map +0 -1
- package/dist/components/Checkbox.js.map +0 -1
- package/dist/components/Clipboard.js.map +0 -1
- package/dist/components/Collapsible.js.map +0 -1
- package/dist/components/ColorPicker.js.map +0 -1
- package/dist/components/Combobox.js.map +0 -1
- package/dist/components/ConfirmDialog.js.map +0 -1
- package/dist/components/DateInput.js.map +0 -1
- package/dist/components/DatePicker.js +0 -7
- package/dist/components/DatePicker.js.map +0 -1
- package/dist/components/DatePickerMobile/index.js +0 -479
- package/dist/components/DatePickerMobile/index.js.map +0 -1
- package/dist/components/DatePickerMobile/wheel.js.map +0 -1
- package/dist/components/Dialog.js.map +0 -1
- package/dist/components/Drawer.js.map +0 -1
- package/dist/components/Field.js.map +0 -1
- package/dist/components/Fieldset.js.map +0 -1
- package/dist/components/FileUpload.js.map +0 -1
- package/dist/components/FilterableSelect.js +0 -210
- package/dist/components/FilterableSelect.js.map +0 -1
- package/dist/components/FilterableSelectMobile.js +0 -167
- package/dist/components/FilterableSelectMobile.js.map +0 -1
- package/dist/components/FocusTrap.js.map +0 -1
- package/dist/components/HoverCard.js +0 -7
- package/dist/components/HoverCard.js.map +0 -1
- package/dist/components/Icon.js.map +0 -1
- package/dist/components/Listbox.js.map +0 -1
- package/dist/components/Menu.js.map +0 -1
- package/dist/components/MoneyInput.js.map +0 -1
- package/dist/components/NumberInput.js.map +0 -1
- package/dist/components/Pagination.js.map +0 -1
- package/dist/components/Popover.js.map +0 -1
- package/dist/components/Portal.js.map +0 -1
- package/dist/components/Presence.js.map +0 -1
- package/dist/components/Progress.js.map +0 -1
- package/dist/components/RadioGroup.js.map +0 -1
- package/dist/components/RatingGroup.js.map +0 -1
- package/dist/components/SearchInput.js.map +0 -1
- package/dist/components/Select.js.map +0 -1
- package/dist/components/SelectMobile/anatomy.js +0 -10
- package/dist/components/SelectMobile/anatomy.js.map +0 -1
- package/dist/components/SelectMobile/index.js +0 -310
- package/dist/components/SelectMobile/index.js.map +0 -1
- package/dist/components/SignaturePad.js.map +0 -1
- package/dist/components/Skeleton.js.map +0 -1
- package/dist/components/Slider.js.map +0 -1
- package/dist/components/Splitter.js.map +0 -1
- package/dist/components/Steps.js.map +0 -1
- package/dist/components/SwipeReveal.js.map +0 -1
- package/dist/components/Switch.js.map +0 -1
- package/dist/components/Tabs.js.map +0 -1
- package/dist/components/TagsInput.js.map +0 -1
- package/dist/components/Toast.js.map +0 -1
- package/dist/components/Toggle.js.map +0 -1
- package/dist/components/ToggleGroup.js.map +0 -1
- package/dist/components/Tooltip.js +0 -7
- package/dist/components/Tooltip.js.map +0 -1
- package/dist/components/Tour.js.map +0 -1
- package/dist/components/TreeView.js.map +0 -1
- package/dist/node_modules/framesync/dist/es/create-render-step.js +0 -54
- package/dist/node_modules/framesync/dist/es/create-render-step.js.map +0 -1
- package/dist/node_modules/framesync/dist/es/index.js +0 -61
- package/dist/node_modules/framesync/dist/es/index.js.map +0 -1
- package/dist/node_modules/framesync/dist/es/on-next-frame.js +0 -8
- package/dist/node_modules/framesync/dist/es/on-next-frame.js.map +0 -1
- package/dist/node_modules/hey-listen/dist/hey-listen.es.js +0 -15
- package/dist/node_modules/hey-listen/dist/hey-listen.es.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/animations/generators/decay.js +0 -24
- package/dist/node_modules/popmotion/dist/es/animations/generators/decay.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/animations/generators/keyframes.js +0 -40
- package/dist/node_modules/popmotion/dist/es/animations/generators/keyframes.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/animations/generators/spring.js +0 -96
- package/dist/node_modules/popmotion/dist/es/animations/generators/spring.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/animations/index.js +0 -94
- package/dist/node_modules/popmotion/dist/es/animations/index.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/animations/inertia.js +0 -74
- package/dist/node_modules/popmotion/dist/es/animations/inertia.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/animations/utils/detect-animation-from-options.js +0 -21
- package/dist/node_modules/popmotion/dist/es/animations/utils/detect-animation-from-options.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/animations/utils/elapsed.js +0 -14
- package/dist/node_modules/popmotion/dist/es/animations/utils/elapsed.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/animations/utils/find-spring.js +0 -68
- package/dist/node_modules/popmotion/dist/es/animations/utils/find-spring.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/easing/index.js +0 -28
- package/dist/node_modules/popmotion/dist/es/easing/index.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/easing/utils.js +0 -13
- package/dist/node_modules/popmotion/dist/es/easing/utils.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/utils/clamp.js +0 -6
- package/dist/node_modules/popmotion/dist/es/utils/clamp.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/utils/hsla-to-rgba.js +0 -35
- package/dist/node_modules/popmotion/dist/es/utils/hsla-to-rgba.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/utils/inc.js +0 -6
- package/dist/node_modules/popmotion/dist/es/utils/inc.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/utils/interpolate.js +0 -69
- package/dist/node_modules/popmotion/dist/es/utils/interpolate.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/utils/mix-color.js +0 -45
- package/dist/node_modules/popmotion/dist/es/utils/mix-color.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/utils/mix-complex.js +0 -61
- package/dist/node_modules/popmotion/dist/es/utils/mix-complex.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/utils/mix.js +0 -6
- package/dist/node_modules/popmotion/dist/es/utils/mix.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/utils/pipe.js +0 -7
- package/dist/node_modules/popmotion/dist/es/utils/pipe.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/utils/progress.js +0 -9
- package/dist/node_modules/popmotion/dist/es/utils/progress.js.map +0 -1
- package/dist/node_modules/popmotion/dist/es/utils/velocity-per-second.js +0 -8
- package/dist/node_modules/popmotion/dist/es/utils/velocity-per-second.js.map +0 -1
- package/dist/node_modules/popmotion/node_modules/tslib/tslib.es6.js +0 -13
- package/dist/node_modules/popmotion/node_modules/tslib/tslib.es6.js.map +0 -1
- package/dist/node_modules/style-value-types/dist/es/color/hex.js +0 -39
- package/dist/node_modules/style-value-types/dist/es/color/hex.js.map +0 -1
- package/dist/node_modules/style-value-types/dist/es/color/hsla.js +0 -16
- package/dist/node_modules/style-value-types/dist/es/color/hsla.js.map +0 -1
- package/dist/node_modules/style-value-types/dist/es/color/index.js +0 -20
- package/dist/node_modules/style-value-types/dist/es/color/index.js.map +0 -1
- package/dist/node_modules/style-value-types/dist/es/color/rgba.js +0 -15
- package/dist/node_modules/style-value-types/dist/es/color/rgba.js.map +0 -1
- package/dist/node_modules/style-value-types/dist/es/color/utils.js +0 -19
- package/dist/node_modules/style-value-types/dist/es/color/utils.js.map +0 -1
- package/dist/node_modules/style-value-types/dist/es/complex/index.js +0 -58
- package/dist/node_modules/style-value-types/dist/es/complex/index.js.map +0 -1
- package/dist/node_modules/style-value-types/dist/es/numbers/index.js +0 -13
- package/dist/node_modules/style-value-types/dist/es/numbers/index.js.map +0 -1
- package/dist/node_modules/style-value-types/dist/es/numbers/units.js +0 -16
- package/dist/node_modules/style-value-types/dist/es/numbers/units.js.map +0 -1
- package/dist/node_modules/style-value-types/dist/es/utils.js +0 -13
- package/dist/node_modules/style-value-types/dist/es/utils.js.map +0 -1
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# Tsumiki Component Guide
|
|
2
|
+
|
|
3
|
+
A single reference for `@plastic-js/tsumiki` covering the component inventory & status (Classification) and the canonical component API pattern (API Pattern).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Part 1 — Component Classification
|
|
8
|
+
|
|
9
|
+
All 51 components are classified along two orthogonal axes.
|
|
10
|
+
|
|
11
|
+
### Axis 1: Development Lifecycle
|
|
12
|
+
|
|
13
|
+
Whether the component is ready for production use or still under active development.
|
|
14
|
+
|
|
15
|
+
| Stage | Definition |
|
|
16
|
+
|-------|------------|
|
|
17
|
+
| **Completed** | Production-ready; API stable. |
|
|
18
|
+
| **In Development** | Still being built; API may change. |
|
|
19
|
+
|
|
20
|
+
### Axis 2: Architectural Foundation
|
|
21
|
+
|
|
22
|
+
Whether the component is built on top of a same-named Ark primitive, or implemented independently.
|
|
23
|
+
|
|
24
|
+
| Foundation | Definition |
|
|
25
|
+
|------------|------------|
|
|
26
|
+
| **Ark-Backed** | Directly wraps a corresponding `@plastic-js/ark` primitive of the same name. |
|
|
27
|
+
| **Custom-Built** | Uses no Ark primitive; implemented with `@plastic-js/plastic`, `@emotion/css`, or the Web platform directly. |
|
|
28
|
+
|
|
29
|
+
### Component Matrix
|
|
30
|
+
|
|
31
|
+
#### Completed · Ark-Backed (30)
|
|
32
|
+
|
|
33
|
+
| Component | Ark Primitive |
|
|
34
|
+
|-----------|---------------|
|
|
35
|
+
| Avatar | `ArkAvatar` |
|
|
36
|
+
| Button | `ark("button")` via factory |
|
|
37
|
+
| Checkbox | `ArkCheckbox` |
|
|
38
|
+
| Collapsible | `ArkCollapsible` |
|
|
39
|
+
| ColorPicker | `ArkColorPicker` |
|
|
40
|
+
| Dialog | `ArkDialog` |
|
|
41
|
+
| Drawer | `ArkDrawer` |
|
|
42
|
+
| FileUpload | `ArkFileUpload` |
|
|
43
|
+
| FocusTrap | `ArkFocusTrap` |
|
|
44
|
+
| Input | `ark("input")` via factory |
|
|
45
|
+
| Menu | `ArkMenu` |
|
|
46
|
+
| NumberInput | `ArkNumberInput` |
|
|
47
|
+
| Pagination | `ArkPagination` |
|
|
48
|
+
| Popover | `ArkPopover` |
|
|
49
|
+
| Portal | `ArkPortal` |
|
|
50
|
+
| Presence | `ArkPresence` |
|
|
51
|
+
| Progress | `ArkProgress` |
|
|
52
|
+
| RadioGroup | `ArkRadioGroup` |
|
|
53
|
+
| RatingGroup | `ArkRatingGroup` |
|
|
54
|
+
| SelectPc | `ArkSelect` |
|
|
55
|
+
| SignaturePad | `ArkSignaturePad` |
|
|
56
|
+
| Slider | `ArkSlider` |
|
|
57
|
+
| Splitter | `ArkSplitter` |
|
|
58
|
+
| Steps | `ArkSteps` |
|
|
59
|
+
| Switch | `ArkSwitch` |
|
|
60
|
+
| Tabs | `ArkTabs` |
|
|
61
|
+
| TagsInput | `ArkTagsInput` |
|
|
62
|
+
| Toast | `ArkToast` |
|
|
63
|
+
| Toggle | `ArkToggle` |
|
|
64
|
+
| ToggleGroup | `ArkToggleGroup` |
|
|
65
|
+
|
|
66
|
+
#### Completed · Custom-Built (15)
|
|
67
|
+
|
|
68
|
+
| Component | Built With |
|
|
69
|
+
|-----------|------------|
|
|
70
|
+
| BottomSheet | `@plastic-js/plastic` + `Portal` |
|
|
71
|
+
| CardNumberInput | Composes `Input` |
|
|
72
|
+
| Clipboard | Web Clipboard API |
|
|
73
|
+
| CloseButton | `@emotion/css` |
|
|
74
|
+
| ConfirmDialog | Composes `Dialog` |
|
|
75
|
+
| DateInput | `DateWheel` utility |
|
|
76
|
+
| Field | `@emotion/css` |
|
|
77
|
+
| Fieldset | `@emotion/css` |
|
|
78
|
+
| Icon | `@emotion/css` |
|
|
79
|
+
| MoneyInput | Composes `Input` |
|
|
80
|
+
| SearchInput | Composes `Input` |
|
|
81
|
+
| Select | Custom state machine with `Loop` |
|
|
82
|
+
| Skeleton | Pure CSS |
|
|
83
|
+
| Spinner | Pure CSS |
|
|
84
|
+
| SwipeReveal | Touch event gestures |
|
|
85
|
+
|
|
86
|
+
#### In Development · Ark-Backed (6)
|
|
87
|
+
|
|
88
|
+
| Component | Ark Primitive |
|
|
89
|
+
|-----------|---------------|
|
|
90
|
+
| Accordion | `ArkAccordion` |
|
|
91
|
+
| Carousel | `ArkCarousel` |
|
|
92
|
+
| Combobox | `ArkCombobox` |
|
|
93
|
+
| Listbox | `ArkListbox` |
|
|
94
|
+
| Tour | `ArkTour` |
|
|
95
|
+
| TreeView | `ArkTreeView` |
|
|
96
|
+
|
|
97
|
+
#### In Development · Custom-Built (0)
|
|
98
|
+
|
|
99
|
+
*No components currently in this quadrant.*
|
|
100
|
+
|
|
101
|
+
### Summary
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
Ark-Backed Custom-Built
|
|
105
|
+
┌─────────────────┬─────────────────┐
|
|
106
|
+
Completed │ 30 │ 15 │ 45
|
|
107
|
+
├─────────────────┼─────────────────┤
|
|
108
|
+
In Development │ 6 │ 0 │ 6
|
|
109
|
+
└─────────────────┴─────────────────┘
|
|
110
|
+
36 15 51
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Part 2 — Component API Pattern
|
|
116
|
+
|
|
117
|
+
This section defines the canonical component API pattern for `@plastic-js/tsumiki`.
|
|
118
|
+
|
|
119
|
+
### Design Goals
|
|
120
|
+
|
|
121
|
+
1. **Simplify Ark APIs** — tsumiki wraps `@plastic-js/ark` components with theme styling, default props, and opinionated presets
|
|
122
|
+
2. **Unified consumer experience** — all components follow the same access pattern
|
|
123
|
+
3. **Escape hatch** — consumers can always reach the raw Ark component when needed
|
|
124
|
+
4. **Controlled-only** — all tsumiki components are controlled; uncontrolled mode (`defaultValue`, `defaultOpen`, `defaultChecked`, etc.) is NOT supported even if the underlying Ark component supports it
|
|
125
|
+
|
|
126
|
+
### Core Rules
|
|
127
|
+
|
|
128
|
+
#### Rule 0: Controlled-Only — No Uncontrolled Mode
|
|
129
|
+
|
|
130
|
+
Tsumiki does not support uncontrolled mode. Every component that manages state (`value`, `open`, `checked`, etc.) must receive it as a controlled signal prop and report changes via a callback. No `defaultValue`, `defaultOpen`, `defaultChecked`, or similar props exist on tsumiki components.
|
|
131
|
+
|
|
132
|
+
```jsx
|
|
133
|
+
// CORRECT: Controlled — consumer owns the state signal
|
|
134
|
+
const isOpen = createSignal(false)
|
|
135
|
+
<Dialog open={isOpen} onOpenChange={v => isOpen(v.open)} />
|
|
136
|
+
|
|
137
|
+
// WRONG: Uncontrolled (not supported)
|
|
138
|
+
<Dialog defaultOpen />
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
If a consumer wants an initial value, they set it in their own `createSignal()` call. No tsumiki component creates internal state for uncontrolled usage.
|
|
142
|
+
|
|
143
|
+
**Rationale:**
|
|
144
|
+
- State ownership is explicit and predictable
|
|
145
|
+
- Components are easier to test and debug
|
|
146
|
+
- The entire API follows a uniform `value`/`onValueChange` contract
|
|
147
|
+
- While Ark primitives may technically accept `default*` props internally, consumers must not rely on this — tsumiki reserves the right to break uncontrolled usage
|
|
148
|
+
|
|
149
|
+
#### Rule 1: The default export IS the render component
|
|
150
|
+
|
|
151
|
+
```jsx
|
|
152
|
+
import { Comp as ArkComp } from '@plastic-js/ark'
|
|
153
|
+
|
|
154
|
+
const Comp = (props = {}) => (
|
|
155
|
+
<ArkComp.Root className={styles} {...rest}>
|
|
156
|
+
{/* tsumiki theme styling */}
|
|
157
|
+
</ArkComp.Root>
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
export default Comp
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The default export is always a **renderable component**. It wraps Ark's root with:
|
|
164
|
+
- CSS-in-JS via `@emotion/css`
|
|
165
|
+
- `var(--tsu-*)` design tokens
|
|
166
|
+
- `splitProps` / `mergeProps` for prop defaults
|
|
167
|
+
- Simplified, opinionated default behavior
|
|
168
|
+
|
|
169
|
+
#### Rule 2: `.origin` maps to raw Ark components
|
|
170
|
+
|
|
171
|
+
```js
|
|
172
|
+
Comp.origin = {
|
|
173
|
+
Root: ArkComp.Root,
|
|
174
|
+
Label: ArkComp.Label,
|
|
175
|
+
Control: ArkComp.Control,
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
- **`.origin`** (lowercase) is the **only** static property on the component
|
|
180
|
+
- It maps tsumiki-friendly names to their raw `@plastic-js/ark` counterparts
|
|
181
|
+
- Only mount what exists on the Ark component — if Ark has no `Label` sub-part, don't add it
|
|
182
|
+
- The `origin` object serves as the **escape hatch** for consumers who need direct access to Ark's full API
|
|
183
|
+
|
|
184
|
+
#### Rule 3: No other static properties
|
|
185
|
+
|
|
186
|
+
```js
|
|
187
|
+
// ❌ WRONG — do not attach sub-components as direct properties
|
|
188
|
+
Comp.Root = Comp
|
|
189
|
+
Comp.Trigger = SomeTrigger
|
|
190
|
+
Comp.Content = SomeContent
|
|
191
|
+
|
|
192
|
+
// ❌ WRONG — do not use Object.assign to spread sub-components
|
|
193
|
+
const Comp = Object.assign(CompRoot, { Root: CompRoot, Trigger, Content })
|
|
194
|
+
|
|
195
|
+
// ✅ CORRECT — only .origin
|
|
196
|
+
Comp.origin = { Root: ArkComp.Root, Trigger: ArkComp.Trigger, Content: ArkComp.Content }
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The component function itself carries **nothing** except `.origin`.
|
|
200
|
+
|
|
201
|
+
#### Rule 4: Components without an Ark counterpart have no `.origin`
|
|
202
|
+
|
|
203
|
+
```js
|
|
204
|
+
// Fully custom component (no Ark import at all)
|
|
205
|
+
import { css } from '@emotion/css'
|
|
206
|
+
|
|
207
|
+
const Spinner = (props = {}) => <div>...</div>
|
|
208
|
+
|
|
209
|
+
// No .origin — there is no Ark counterpart
|
|
210
|
+
export default Spinner
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### Rule 5: Sub-components (when needed) are named exports
|
|
214
|
+
|
|
215
|
+
For components that have meaningful, tsumiki-wrapped sub-components (see [Multi-Part Component Pattern](#multi-part-component-pattern)), sub-components are exported as **named exports** from the module, NOT attached to the default export.
|
|
216
|
+
|
|
217
|
+
#### Rule 6: Dual export (default + named)
|
|
218
|
+
|
|
219
|
+
Every component module **must** export both a default and a named export for the top-level component:
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
export default Comp
|
|
223
|
+
export { Comp }
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
This ensures consumers can import using either style:
|
|
227
|
+
|
|
228
|
+
```js
|
|
229
|
+
import Comp from '@plastic-js/tsumiki/components/Comp.jsx'
|
|
230
|
+
import { Comp } from '@plastic-js/tsumiki/components/Comp.jsx'
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
When the internal variable name differs from the component name, use an alias:
|
|
234
|
+
|
|
235
|
+
```js
|
|
236
|
+
export default Root
|
|
237
|
+
export { Root as FileUpload }
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Naming Conventions
|
|
241
|
+
|
|
242
|
+
| Element | Convention | Example |
|
|
243
|
+
|---------|-----------|---------|
|
|
244
|
+
| Ark import alias | `Ark` + PascalCase name | `import { Dialog as ArkDialog }` |
|
|
245
|
+
| Component function | PascalCase, same as default export name | `const Dialog = (props) => ...` |
|
|
246
|
+
| origin keys | PascalCase, matching Ark sub-part names | `{ Root, Trigger, Content }` |
|
|
247
|
+
| `.origin` property | lowercase `origin` | `Dialog.origin = { ... }` |
|
|
248
|
+
| CSS class variables | `camelCase` + `Class` suffix | `rootClass`, `contentClass` |
|
|
249
|
+
|
|
250
|
+
### Consumer Usage
|
|
251
|
+
|
|
252
|
+
#### Simple component (single wrapper)
|
|
253
|
+
|
|
254
|
+
```jsx
|
|
255
|
+
import { Button } from '@plastic-js/tsumiki'
|
|
256
|
+
|
|
257
|
+
// Primary usage: tsumiki-styled
|
|
258
|
+
<Button solid>Click me</Button>
|
|
259
|
+
|
|
260
|
+
// Escape hatch: raw Ark API
|
|
261
|
+
<Button.origin.Root>...</Button.origin.Root>
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
#### Simple component wrapping multiple Ark sub-parts
|
|
265
|
+
|
|
266
|
+
```jsx
|
|
267
|
+
import { Checkbox } from '@plastic-js/tsumiki'
|
|
268
|
+
|
|
269
|
+
// Primary usage: tsumiki-styled (wraps Root + Control + Indicator + Label + HiddenInput)
|
|
270
|
+
<Checkbox>Accept terms</Checkbox>
|
|
271
|
+
|
|
272
|
+
// Escape hatch: individual raw Ark sub-parts
|
|
273
|
+
<Checkbox.origin.Root>
|
|
274
|
+
<Checkbox.origin.Control>
|
|
275
|
+
<Checkbox.origin.Indicator />
|
|
276
|
+
</Checkbox.origin.Control>
|
|
277
|
+
</Checkbox.origin.Root>
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
#### Multi-part component (see below)
|
|
281
|
+
|
|
282
|
+
```jsx
|
|
283
|
+
import Menu, { MenuTrigger, MenuContent, MenuItem } from '@plastic-js/tsumiki'
|
|
284
|
+
|
|
285
|
+
<Menu>
|
|
286
|
+
<MenuTrigger>Open</MenuTrigger>
|
|
287
|
+
<MenuContent>
|
|
288
|
+
<MenuItem>Action</MenuItem>
|
|
289
|
+
</MenuContent>
|
|
290
|
+
</Menu>
|
|
291
|
+
|
|
292
|
+
// Escape hatch
|
|
293
|
+
<Menu.origin.Root>
|
|
294
|
+
<Menu.origin.Trigger>...</Menu.origin.Trigger>
|
|
295
|
+
<Menu.origin.Content>...</Menu.origin.Content>
|
|
296
|
+
</Menu.origin.Root>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Multi-Part Component Pattern
|
|
300
|
+
|
|
301
|
+
For components that have meaningful tsumiki-wrapped sub-components (e.g., Menu, Dialog, Accordion), each sub-component is a named export:
|
|
302
|
+
|
|
303
|
+
```jsx
|
|
304
|
+
import { Menu as ArkMenu } from '@plastic-js/ark'
|
|
305
|
+
|
|
306
|
+
// Default export: the root wrapper
|
|
307
|
+
const Menu = (props = {}) => (
|
|
308
|
+
<ArkMenu.Root className={rootClass} {...rest}>
|
|
309
|
+
{children}
|
|
310
|
+
</ArkMenu.Root>
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
// Named exports: tsumiki-wrapped sub-components
|
|
314
|
+
export const MenuTrigger = (props = {}) => (
|
|
315
|
+
<ArkMenu.Trigger className={triggerClass} {...rest}>
|
|
316
|
+
{children}
|
|
317
|
+
</ArkMenu.Trigger>
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
export const MenuContent = (props = {}) => (
|
|
321
|
+
<ArkMenu.Content className={contentClass} {...rest}>
|
|
322
|
+
{children}
|
|
323
|
+
</ArkMenu.Content>
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
Menu.origin = {
|
|
327
|
+
Root: ArkMenu.Root,
|
|
328
|
+
Trigger: ArkMenu.Trigger,
|
|
329
|
+
Content: ArkMenu.Content,
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export default Menu
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
#### Barrel exports for multi-part components
|
|
336
|
+
|
|
337
|
+
In `src/index.js`, both default and named exports are re-exported:
|
|
338
|
+
|
|
339
|
+
```js
|
|
340
|
+
export {
|
|
341
|
+
default as Menu,
|
|
342
|
+
MenuTrigger,
|
|
343
|
+
MenuContent,
|
|
344
|
+
MenuItem,
|
|
345
|
+
MenuSeparator,
|
|
346
|
+
} from './components/Menu.jsx'
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### File Structure
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
src/components/Comp.jsx
|
|
353
|
+
├── imports (@emotion/css, @plastic-js/ark, @plastic-js/plastic)
|
|
354
|
+
├── CSS class definitions (rootClass, triggerClass, etc.)
|
|
355
|
+
├── Component function (default export)
|
|
356
|
+
├── [Named exports for sub-components, if multi-part]
|
|
357
|
+
├── .origin assignment
|
|
358
|
+
├── export default Comp
|
|
359
|
+
└── export { Comp }
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plastic-js/tsumiki",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.24",
|
|
4
4
|
"description": "A UI component library for Plastic JS.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "tigre",
|
|
@@ -27,10 +27,15 @@
|
|
|
27
27
|
".": {
|
|
28
28
|
"import": "./dist/index.js",
|
|
29
29
|
"default": "./dist/index.js"
|
|
30
|
-
}
|
|
30
|
+
},
|
|
31
|
+
"./styles": "./dist/tsumiki.css",
|
|
32
|
+
"./tsumiki.css": "./dist/tsumiki.css",
|
|
33
|
+
"./styles/*": "./src/styles/*"
|
|
31
34
|
},
|
|
32
35
|
"files": [
|
|
33
36
|
"dist",
|
|
37
|
+
"src/styles",
|
|
38
|
+
"docs",
|
|
34
39
|
"LICENSE",
|
|
35
40
|
"README.md"
|
|
36
41
|
],
|
|
@@ -40,23 +45,28 @@
|
|
|
40
45
|
},
|
|
41
46
|
"scripts": {
|
|
42
47
|
"dev": "vite",
|
|
43
|
-
"build": "vite build",
|
|
48
|
+
"build": "vite build && npm run build:styles",
|
|
49
|
+
"build:styles": "vite build --config vite.styles.config.js && cp dist-styles/*.css dist/tsumiki.css && rm -rf dist-styles",
|
|
44
50
|
"prepublishOnly": "npm run build",
|
|
45
51
|
"preview": "vite preview",
|
|
52
|
+
"theme": "node scripts/theme.js",
|
|
46
53
|
"e2e:repro": "node e2e/dlgcbx-repro.mjs"
|
|
47
54
|
},
|
|
48
55
|
"dependencies": {
|
|
49
56
|
"@emotion/css": "^11.13.5",
|
|
50
|
-
"@
|
|
51
|
-
"@plastic-js/plastic": "^1.0.22",
|
|
57
|
+
"@zag-js/select": "1.40.0",
|
|
52
58
|
"popmotion": "^11.0.5"
|
|
53
59
|
},
|
|
54
60
|
"peerDependencies": {
|
|
55
|
-
"@
|
|
61
|
+
"@plastic-js/ark": "^1.0.16",
|
|
62
|
+
"@plastic-js/plastic": "^1.0.22"
|
|
56
63
|
},
|
|
57
64
|
"devDependencies": {
|
|
58
65
|
"@babel/core": "^7.29.7",
|
|
66
|
+
"@plastic-js/ark": "^1.0.16",
|
|
59
67
|
"@plastic-js/babel-preset-plastic": "^0.1.11",
|
|
68
|
+
"@plastic-js/plastic": "^1.0.22",
|
|
69
|
+
"@radix-ui/colors": "^3.0.0",
|
|
60
70
|
"@zag-js/combobox": "1.40.0",
|
|
61
71
|
"puppeteer-core": "^25.1.0",
|
|
62
72
|
"vite": "^8.0.15"
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
@import './theme.css';
|
|
2
|
+
@import '@radix-ui/colors/red.css';
|
|
3
|
+
@import '@radix-ui/colors/red-alpha.css';
|
|
4
|
+
@import '@radix-ui/colors/red-dark.css';
|
|
5
|
+
@import '@radix-ui/colors/red-dark-alpha.css';
|
|
6
|
+
@import '@radix-ui/colors/green.css';
|
|
7
|
+
@import '@radix-ui/colors/green-alpha.css';
|
|
8
|
+
@import '@radix-ui/colors/green-dark.css';
|
|
9
|
+
@import '@radix-ui/colors/green-dark-alpha.css';
|
|
10
|
+
@import '@radix-ui/colors/amber.css';
|
|
11
|
+
@import '@radix-ui/colors/amber-alpha.css';
|
|
12
|
+
@import '@radix-ui/colors/amber-dark.css';
|
|
13
|
+
@import '@radix-ui/colors/amber-dark-alpha.css';
|
|
14
|
+
|
|
15
|
+
:root {
|
|
16
|
+
--tsu-bg: var(--tsu-neutral-1);
|
|
17
|
+
--tsu-fg: var(--tsu-neutral-12);
|
|
18
|
+
|
|
19
|
+
/* Info (accent) — full 12-step palette */
|
|
20
|
+
--tsu-info-1: var(--tsu-accent-1);
|
|
21
|
+
--tsu-info-2: var(--tsu-accent-2);
|
|
22
|
+
--tsu-info-3: var(--tsu-accent-3);
|
|
23
|
+
--tsu-info-4: var(--tsu-accent-4);
|
|
24
|
+
--tsu-info-5: var(--tsu-accent-5);
|
|
25
|
+
--tsu-info-6: var(--tsu-accent-6);
|
|
26
|
+
--tsu-info-7: var(--tsu-accent-7);
|
|
27
|
+
--tsu-info-8: var(--tsu-accent-8);
|
|
28
|
+
--tsu-info-9: var(--tsu-accent-9);
|
|
29
|
+
--tsu-info-10: var(--tsu-accent-10);
|
|
30
|
+
--tsu-info-11: var(--tsu-accent-11);
|
|
31
|
+
--tsu-info-12: var(--tsu-accent-12);
|
|
32
|
+
|
|
33
|
+
/* Danger (red) */
|
|
34
|
+
--tsu-danger-1: var(--red-1);
|
|
35
|
+
--tsu-danger-2: var(--red-2);
|
|
36
|
+
--tsu-danger-3: var(--red-3);
|
|
37
|
+
--tsu-danger-4: var(--red-4);
|
|
38
|
+
--tsu-danger-5: var(--red-5);
|
|
39
|
+
--tsu-danger-6: var(--red-6);
|
|
40
|
+
--tsu-danger-7: var(--red-7);
|
|
41
|
+
--tsu-danger-8: var(--red-8);
|
|
42
|
+
--tsu-danger-9: var(--red-9);
|
|
43
|
+
--tsu-danger-10: var(--red-10);
|
|
44
|
+
--tsu-danger-11: var(--red-11);
|
|
45
|
+
--tsu-danger-12: var(--red-12);
|
|
46
|
+
|
|
47
|
+
/* Success (green) */
|
|
48
|
+
--tsu-success-1: var(--green-1);
|
|
49
|
+
--tsu-success-2: var(--green-2);
|
|
50
|
+
--tsu-success-3: var(--green-3);
|
|
51
|
+
--tsu-success-4: var(--green-4);
|
|
52
|
+
--tsu-success-5: var(--green-5);
|
|
53
|
+
--tsu-success-6: var(--green-6);
|
|
54
|
+
--tsu-success-7: var(--green-7);
|
|
55
|
+
--tsu-success-8: var(--green-8);
|
|
56
|
+
--tsu-success-9: var(--green-9);
|
|
57
|
+
--tsu-success-10: var(--green-10);
|
|
58
|
+
--tsu-success-11: var(--green-11);
|
|
59
|
+
--tsu-success-12: var(--green-12);
|
|
60
|
+
|
|
61
|
+
/* Warning (amber) */
|
|
62
|
+
--tsu-warning-1: var(--amber-1);
|
|
63
|
+
--tsu-warning-2: var(--amber-2);
|
|
64
|
+
--tsu-warning-3: var(--amber-3);
|
|
65
|
+
--tsu-warning-4: var(--amber-4);
|
|
66
|
+
--tsu-warning-5: var(--amber-5);
|
|
67
|
+
--tsu-warning-6: var(--amber-6);
|
|
68
|
+
--tsu-warning-7: var(--amber-7);
|
|
69
|
+
--tsu-warning-8: var(--amber-8);
|
|
70
|
+
--tsu-warning-9: var(--amber-9);
|
|
71
|
+
--tsu-warning-10: var(--amber-10);
|
|
72
|
+
--tsu-warning-11: var(--amber-11);
|
|
73
|
+
--tsu-warning-12: var(--amber-12);
|
|
74
|
+
|
|
75
|
+
/* Neutral Alpha Overlay (used for shadows/elevation) */
|
|
76
|
+
--tsu-neutral-alpha-1: var(--olive-a1);
|
|
77
|
+
--tsu-neutral-alpha-2: var(--olive-a2);
|
|
78
|
+
--tsu-neutral-alpha-3: var(--olive-a3);
|
|
79
|
+
--tsu-neutral-alpha-4: var(--olive-a4);
|
|
80
|
+
--tsu-neutral-alpha-5: var(--olive-a5);
|
|
81
|
+
--tsu-neutral-alpha-6: var(--olive-a6);
|
|
82
|
+
--tsu-neutral-alpha-7: var(--olive-a7);
|
|
83
|
+
--tsu-neutral-alpha-8: var(--olive-a8);
|
|
84
|
+
--tsu-neutral-alpha-9: var(--olive-a9);
|
|
85
|
+
--tsu-neutral-alpha-10: var(--olive-a10);
|
|
86
|
+
--tsu-neutral-alpha-11: var(--olive-a11);
|
|
87
|
+
--tsu-neutral-alpha-12: var(--olive-a12);
|
|
88
|
+
|
|
89
|
+
/* Disabled State */
|
|
90
|
+
--tsu-disabled-bg: var(--tsu-neutral-3);
|
|
91
|
+
--tsu-disabled-fg: var(--tsu-neutral-9);
|
|
92
|
+
--tsu-disabled-border: var(--tsu-neutral-7);
|
|
93
|
+
|
|
94
|
+
/* Focus State */
|
|
95
|
+
--tsu-focus-bg: var(--tsu-neutral-2);
|
|
96
|
+
--tsu-focus-border: var(--tsu-accent-8);
|
|
97
|
+
|
|
98
|
+
/* Legacy Aliases — map old variable names to new token system */
|
|
99
|
+
--ink: var(--tsu-fg);
|
|
100
|
+
--muted: var(--tsu-neutral-11);
|
|
101
|
+
--accent: var(--tsu-accent-9);
|
|
102
|
+
--surface: var(--tsu-bg);
|
|
103
|
+
--bg: var(--tsu-neutral-2);
|
|
104
|
+
--border: var(--tsu-neutral-7);
|
|
105
|
+
--danger: var(--tsu-danger-9);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Dark mode: use a lighter page background */
|
|
109
|
+
:root.dark {
|
|
110
|
+
--tsu-bg: var(--tsu-neutral-3);
|
|
111
|
+
--tsu-fg: #ffffff;
|
|
112
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './reset.css';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--tsu-radius-round: 9999px;
|
|
3
|
+
|
|
4
|
+
--tsu-radius-l3-xs: 16px;
|
|
5
|
+
--tsu-radius-l2-xs: 8px;
|
|
6
|
+
--tsu-radius-l1-xs: 2px;
|
|
7
|
+
|
|
8
|
+
--tsu-radius-l3-sm: 16px;
|
|
9
|
+
--tsu-radius-l2-sm: 8px;
|
|
10
|
+
--tsu-radius-l1-sm: 2px;
|
|
11
|
+
|
|
12
|
+
--tsu-radius-l3-md: 16px;
|
|
13
|
+
--tsu-radius-l2-md: 8px;
|
|
14
|
+
--tsu-radius-l1-md: 4px;
|
|
15
|
+
|
|
16
|
+
--tsu-radius-l3-lg: 16px;
|
|
17
|
+
--tsu-radius-l2-lg: 8px;
|
|
18
|
+
--tsu-radius-l1-lg: 6px;
|
|
19
|
+
|
|
20
|
+
--tsu-radius-l3-xl: 16px;
|
|
21
|
+
--tsu-radius-l2-xl: 8px;
|
|
22
|
+
--tsu-radius-l1-xl: 8px;
|
|
23
|
+
|
|
24
|
+
--tsu-radius-l3-xxl: 16px;
|
|
25
|
+
--tsu-radius-l2-xxl: 8px;
|
|
26
|
+
--tsu-radius-l1-xxl: 16px;
|
|
27
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
@import './tokens.css';
|
|
2
|
+
|
|
3
|
+
/* ── Modern CSS Reset ─────────────────────────────────────────────── */
|
|
4
|
+
*,
|
|
5
|
+
*::before,
|
|
6
|
+
*::after {
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
html {
|
|
11
|
+
-moz-text-size-adjust: none;
|
|
12
|
+
-webkit-text-size-adjust: none;
|
|
13
|
+
text-size-adjust: none;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
* {
|
|
17
|
+
margin: 0;
|
|
18
|
+
padding: 0;
|
|
19
|
+
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
body {
|
|
23
|
+
min-height: 100vh;
|
|
24
|
+
font-family: var(--tsu-font-family);
|
|
25
|
+
font-size: var(--tsu-font-size-md);
|
|
26
|
+
line-height: var(--tsu-line-height);
|
|
27
|
+
color: var(--tsu-fg);
|
|
28
|
+
background-color: var(--tsu-bg);
|
|
29
|
+
text-rendering: optimizeLegibility;
|
|
30
|
+
-webkit-font-smoothing: antialiased;
|
|
31
|
+
-moz-osx-font-smoothing: grayscale;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
img,
|
|
35
|
+
picture,
|
|
36
|
+
video,
|
|
37
|
+
canvas,
|
|
38
|
+
svg {
|
|
39
|
+
display: block;
|
|
40
|
+
max-inline-size: 100%;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
input,
|
|
44
|
+
button,
|
|
45
|
+
textarea,
|
|
46
|
+
select {
|
|
47
|
+
font: inherit;
|
|
48
|
+
color: inherit;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
p,
|
|
52
|
+
h1,
|
|
53
|
+
h2,
|
|
54
|
+
h3,
|
|
55
|
+
h4,
|
|
56
|
+
h5,
|
|
57
|
+
h6 {
|
|
58
|
+
overflow-wrap: break-word;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
p {
|
|
62
|
+
text-wrap: pretty;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
h1,
|
|
66
|
+
h2,
|
|
67
|
+
h3,
|
|
68
|
+
h4,
|
|
69
|
+
h5,
|
|
70
|
+
h6 {
|
|
71
|
+
text-wrap: balance;
|
|
72
|
+
font-weight: 600;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
a {
|
|
76
|
+
color: inherit;
|
|
77
|
+
text-decoration: none;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
textarea:not([rows]) {
|
|
81
|
+
min-height: 10em;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
:target {
|
|
85
|
+
scroll-margin-block: 5ex;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
:where(ul, ol) {
|
|
89
|
+
list-style: none;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
:where(table) {
|
|
93
|
+
border-collapse: collapse;
|
|
94
|
+
border-spacing: 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
:where(button) {
|
|
98
|
+
appearance: none;
|
|
99
|
+
background: none;
|
|
100
|
+
border: none;
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
:where([hidden]) {
|
|
105
|
+
display: none;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
input[type="search"]::-webkit-search-cancel-button,
|
|
109
|
+
input[type="search"]::-ms-clear {
|
|
110
|
+
display: none;
|
|
111
|
+
}
|