@takeoff-ui/react-spar 0.1.0-beta.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.
package/README.md ADDED
@@ -0,0 +1,212 @@
1
+ # @takeoff-ui/react-spar
2
+
3
+ Current-phase React package for Takeoff components backed by
4
+ `@turkish-technology/spar`. Components ship as compound surfaces: state lives on
5
+ the root and structure lives in named subcomponents.
6
+
7
+ The public API uses React primitive vocabulary for Accordion state (`value`,
8
+ `defaultValue`, `onValueChange`, item `value`) while preserving visual Takeoff
9
+ vocabulary (`type`, `mode`, `size`) and translating framework mechanics into
10
+ React conventions (`default*` props, `on*` callbacks, and compound children
11
+ instead of Web Component slots).
12
+
13
+ ## Current Surface
14
+
15
+ The package currently exports:
16
+
17
+ - `Accordion`
18
+ - `Button`
19
+ - `Drawer`
20
+ - `Tooltip`
21
+ - `TakeoffSparProvider`
22
+ - customization and theme types from the package root
23
+
24
+ See the docs site for components queued next. Additional wrappers are added only
25
+ after their component contract is source-backed and any upstream Spar behavior
26
+ gaps are resolved.
27
+
28
+ ## Reference
29
+
30
+ - Spar documentation: https://spar.app.turkishtechlab.com/
31
+ - Spar Accordion reference:
32
+ https://spar.app.turkishtechlab.com/docs/Components/Accordion
33
+
34
+ ## Install
35
+
36
+ `@takeoff-ui/react-spar` currently targets React 19.x only.
37
+
38
+ ```bash
39
+ pnpm add @takeoff-ui/react-spar
40
+ ```
41
+
42
+ `@takeoff-design/tokens` and `@turkish-technology/spar` are direct dependencies
43
+ of `@takeoff-ui/react-spar` — you don't need to install them separately. Add
44
+ either one to your own `package.json` only if your app imports from it directly
45
+ (for example, when overriding token CSS variables from an entry stylesheet, or
46
+ when using Spar primitives that `react-spar` does not re-export).
47
+
48
+ `@takeoff-ui/react-spar` does not bundle component CSS. Import the token
49
+ stylesheet once at the app shell or entrypoint:
50
+
51
+ ```ts
52
+ import '@takeoff-design/tokens/css/default/theme.css';
53
+ ```
54
+
55
+ ## Usage
56
+
57
+ ```tsx
58
+ import '@takeoff-design/tokens/css/default/theme.css';
59
+ import { Accordion, TakeoffSparProvider } from '@takeoff-ui/react-spar';
60
+
61
+ export function Example() {
62
+ return (
63
+ <TakeoffSparProvider>
64
+ <Accordion defaultValue="baggage">
65
+ <Accordion.Item value="baggage">
66
+ <Accordion.Header>
67
+ <Accordion.Trigger>Baggage allowance</Accordion.Trigger>
68
+ </Accordion.Header>
69
+ <Accordion.Content>
70
+ Review your cabin and checked baggage limits before your trip.
71
+ </Accordion.Content>
72
+ </Accordion.Item>
73
+
74
+ <Accordion.Item value="changes">
75
+ <Accordion.Header>
76
+ <Accordion.Trigger>Flight changes</Accordion.Trigger>
77
+ </Accordion.Header>
78
+ <Accordion.Content>
79
+ Change rules depend on the fare family selected during booking.
80
+ </Accordion.Content>
81
+ </Accordion.Item>
82
+ </Accordion>
83
+ </TakeoffSparProvider>
84
+ );
85
+ }
86
+ ```
87
+
88
+ `TakeoffSparProvider` accepts `colorMode` (`'light' | 'dark'`, default
89
+ `'light'`), an optional `locale` string, and an optional `components`
90
+ customization map. The provider renders a `display: contents` wrapper that
91
+ writes `data-theme` from `colorMode` and `lang` from `locale`.
92
+
93
+ ## Accordion
94
+
95
+ ```tsx
96
+ <Accordion multiple defaultValue={['one']}>
97
+ <Accordion.Item value="one">
98
+ <Accordion.Header>
99
+ <Accordion.Trigger>
100
+ FAQ
101
+ <Accordion.Indicator />
102
+ </Accordion.Trigger>
103
+ </Accordion.Header>
104
+ <Accordion.Content>Answer content</Accordion.Content>
105
+ </Accordion.Item>
106
+ </Accordion>
107
+ ```
108
+
109
+ - Root behavior props: `value`, `defaultValue`, `multiple`, `onValueChange`,
110
+ `collapsible`, `disabled`, `orientation`.
111
+ - Root visual props: `type`, `mode`, `size`.
112
+ - Trigger leading content: `startContent` prop on `Accordion.Trigger`.
113
+ - Item props: required `value`, optional `disabled`.
114
+ - Public parts: `Accordion.Item`, `Accordion.Header`, `Accordion.Trigger`,
115
+ `Accordion.Indicator`, `Accordion.Content`.
116
+ - The disclosure indicator is opt-in: drop `<Accordion.Indicator />` into the
117
+ trigger to render the default chevron, override its children to swap glyphs,
118
+ or omit it to ship a trigger without a visual affordance. Placement (left vs
119
+ right of the title) follows where you put it inside the trigger.
120
+ - Web Component shortcuts such as item-level `active`, `header`, and custom DOM
121
+ active-index events are intentionally not part of the React surface; use root
122
+ state props and compound children instead.
123
+
124
+ ## Customization
125
+
126
+ Every public component part exposes the same customization layers:
127
+
128
+ - `className`: appended to the canonical root slot class.
129
+ - `classNames`: per-slot extra classes, concatenated with canonical `tk-*`
130
+ classes.
131
+ - `slotProps`: per-slot HTML attributes, shallow-merged below canonical wrapper
132
+ attributes.
133
+ - provider `components`: global defaults, classes, and slot props keyed by
134
+ component name.
135
+
136
+ Canonical `tk-*` classes and `data-slot` attributes are always preserved.
137
+
138
+ ### Theme-level Defaults
139
+
140
+ ```tsx
141
+ <TakeoffSparProvider
142
+ components={{
143
+ Accordion: {
144
+ defaultProps: { size: 'large' },
145
+ className: 'travel-faq',
146
+ },
147
+ AccordionTrigger: {
148
+ slotProps: { root: { 'aria-describedby': 'faq-trigger-hint' } },
149
+ },
150
+ }}
151
+ >
152
+ {children}
153
+ </TakeoffSparProvider>
154
+ ```
155
+
156
+ Instance props override provider defaults. Instance `classNames` and `slotProps`
157
+ override provider entries for the same slot, while canonical wrapper attributes
158
+ remain in place.
159
+
160
+ ### Per-instance Classes
161
+
162
+ ```tsx
163
+ <Accordion.Item value="faq" classNames={{ root: 'faq-item' }}>
164
+ <Accordion.Header>
165
+ <Accordion.Trigger classNames={{ root: 'faq-trigger' }}>
166
+ FAQ
167
+ </Accordion.Trigger>
168
+ </Accordion.Header>
169
+ <Accordion.Content>Answer text</Accordion.Content>
170
+ </Accordion.Item>
171
+ ```
172
+
173
+ ### Per-instance Slot Props
174
+
175
+ ```tsx
176
+ <Accordion.Item
177
+ value="faq"
178
+ slotProps={{
179
+ root: { 'aria-describedby': 'faq-note' },
180
+ }}
181
+ >
182
+ <Accordion.Header>
183
+ <Accordion.Trigger>FAQ</Accordion.Trigger>
184
+ </Accordion.Header>
185
+ <Accordion.Content>Answer text</Accordion.Content>
186
+ </Accordion.Item>
187
+ ```
188
+
189
+ ### Custom Indicator
190
+
191
+ ```tsx
192
+ <Accordion>
193
+ <Accordion.Item value="faq">
194
+ <Accordion.Header>
195
+ <Accordion.Trigger>
196
+ FAQ
197
+ <Accordion.Indicator>
198
+ {({ isOpen }) => (isOpen ? <span>-</span> : <span>+</span>)}
199
+ </Accordion.Indicator>
200
+ </Accordion.Trigger>
201
+ </Accordion.Header>
202
+ <Accordion.Content>Answer text</Accordion.Content>
203
+ </Accordion.Item>
204
+ </Accordion>
205
+ ```
206
+
207
+ Custom arrow content is rendered inside the canonical `.tk-accordion-item-arrow`
208
+ owner node so recipes keep their stable selector.
209
+
210
+ `Accordion.Indicator` is opt-in — omit it to render a trigger without a
211
+ disclosure affordance. Its owner node carries the canonical
212
+ `.tk-accordion-item-indicator` class so recipes keep a stable selector.