@simple-base/contracts 0.1.0 → 0.1.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 (2) hide show
  1. package/README.md +79 -91
  2. package/package.json +6 -1
package/README.md CHANGED
@@ -1,12 +1,16 @@
1
1
  # @simple-base/contracts
2
2
 
3
- Shared component option types and default constants for framework adapters such as
4
- Solid and React. CSS owns styling; adapters own rendering, native props, and
5
- behavior. This package has no runtime dependencies.
3
+ Framework-neutral component options and default values for Simple Base adapters.
6
4
 
7
- `packages/css/styles/` is the source of truth for supported styling options. Only
8
- components with shared custom options need a contract. There are no class-name
9
- maps, attribute-name maps, CSS-property maps, or class-only contracts.
5
+ CSS owns styling. Adapters own rendering, native props, and behavior. This package holds the shared custom options that more than one adapter needs — the types you pass to a component and the defaults applied when you omit them. It has no runtime dependencies.
6
+
7
+ **Most applications don't need this package directly.** Install [@simple-base/solid](https://www.npmjs.com/package/@simple-base/solid) and it re-exports the option types it uses. Install this package when you are writing an adapter for another framework, or when you need the shared option types without a renderer.
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ pnpm add @simple-base/contracts
13
+ ```
10
14
 
11
15
  ## Usage
12
16
 
@@ -17,105 +21,89 @@ import {
17
21
  type ButtonSize,
18
22
  type ButtonVariant,
19
23
  } from "@simple-base/contracts";
20
- ```
21
24
 
22
- The same exports are available from `@simple-base/contracts/button`. Other
23
- subpaths are `/badge`, `/card`, `/combobox`, `/placement`, `/select`, and
24
- `/status`.
25
+ export function Button(props: ButtonOptions) {
26
+ const variant = props.variant ?? buttonDefaults.variant;
27
+ const size = props.size ?? buttonDefaults.size;
25
28
 
26
- Adapters compose the shared options with their framework's native element props,
27
- apply defaults when options are omitted, and emit the appropriate CSS classes and
28
- attributes directly. Share framework-neutral public configuration and value
29
- callbacks. Children, refs, framework-specific DOM events, native element prop
30
- interfaces, internal context, and accessibility implementation stay in the adapters.
31
- Every adapter part accepts a reactive `class` plus the native attributes for the
32
- element it renders, excluding the attributes the widget owns. Widget event
33
- handlers are composed with consumer handlers rather than replaced.
29
+ return { "data-variant": variant, "data-size": size };
30
+ }
31
+ ```
32
+
33
+ The same exports are available per component, which keeps imports narrow:
34
34
 
35
35
  ```ts
36
- export type ButtonOptions = {
37
- variant?: ButtonVariant;
38
- size?: ButtonSize;
39
- };
40
-
41
- export const buttonDefaults = {
42
- variant: "primary",
43
- size: "medium",
44
- } as const satisfies Required<ButtonOptions>;
36
+ import { buttonDefaults, type ButtonVariant } from "@simple-base/contracts/button";
45
37
  ```
46
38
 
47
- Types are erased from runtime JavaScript. Only the default constants are runtime
48
- exports; there are no allowed-value arrays without a runtime use case.
39
+ Subpaths: `/badge` · `/button` · `/card` · `/combobox` · `/placement` · `/select` · `/status` · `/table`
49
40
 
50
- ## Available options
41
+ ## Options reference
51
42
 
52
43
  | Component | Types | Defaults |
53
44
  | ----------- | ---------------------------------------------- | ------------------------------------- |
54
45
  | Button | `ButtonVariant`, `ButtonSize`, `ButtonOptions` | `buttonDefaults`: `primary`, `medium` |
55
46
  | Badge | `BadgeVariant`, `BadgeSize`, `BadgeOptions` | `badgeDefaults`: `default`, `medium` |
56
47
  | Card | `CardVariant`, `CardOptions` | `cardDefaults`: `padding: false` |
57
- | Combobox | `ComboboxOption`, `ComboboxOptions` | No defaults |
58
- | Select | `SelectOption`, `SelectOptions` | No defaults |
59
- | Status line | `StatusValue`, `StatusOptions` | No default status |
60
- | Alert | `AlertStatus`, `AlertOptions` | No default status |
48
+ | Combobox | `ComboboxOption`, `ComboboxOptions` | |
49
+ | Select | `SelectOption`, `SelectOptions` | |
50
+ | Status line | `StatusValue`, `StatusOptions` | |
51
+ | Alert | `AlertStatus`, `AlertOptions` | |
61
52
  | Toast | `ToastStatus`, `ToastOptions` | `toastDefaults`: `status: "success"` |
53
+ | Table cell | `TableCellVariant`, `TableCellOptions` | — |
62
54
 
63
- - Button variants: `primary`, `secondary`, `tertiary`, `ghost`, `danger`,
64
- `danger-subtle`. Sizes: `small`, `medium`, `large`. Apply the default attributes
65
- explicitly; the bare CSS class is not identical to every default variant rule.
66
- - Badge variants: `default`, `success`, `danger`, `warning`, `info`, `accent`,
67
- `command`, `outline`, `muted`. Sizes: `small`, `medium`.
68
- - Card variants: `flat`, `rule`. Omit `variant` for the base card; there is no
69
- explicit `default` variant. `padding` is boolean and maps to
70
- `data-padding="true"` when enabled.
71
- - `ComboboxOption` contains `label`, a unique `value`, and optional `disabled`.
72
- `ComboboxOptions` defines the shared root API: required `id`, `label`, `options`,
73
- and `onValueChange`, plus optional `placeholder`, `value`, `disabled`,
74
- `invalid`, `required`, `name`, `placement`, and `onOpenChange`. The callback
75
- receives the selected option's string value, or an empty string when selection
76
- is cleared. Adapters add their own children type and keep context and rendering
77
- internal.
78
- - `SelectOption` mirrors `ComboboxOption`, and `SelectOptions` mirrors
79
- `ComboboxOptions` for the keyboard-driven single-select. The `placeholder`
80
- string renders in place of the value text until an option is selected. Both
81
- option lists stay independent so each adapter can evolve its own surface.
82
- - `value` is the controlled counterpart of `onValueChange`. An empty string means
83
- no selection, and omitting `value` leaves the component uncontrolled. Adapters
84
- must therefore treat `""` as a controlled empty selection, not as uncontrolled.
85
- - `disabled` dims and blocks the field, `invalid` switches the border and focus
86
- ring to the danger tokens, and `required` adds the label marker. `placement` is
87
- the shared `top`/`bottom` union with `-start` and `-end` variants and picks the
88
- popup side; it is deliberately narrower than the adapter's positioning options,
89
- not a pass-through. `onOpenChange` reports popup visibility for lazy loading
90
- and analytics.
91
- - `name` has different meaning per component. Combobox applies it to the visible
92
- input, so the submitted value is the option label, not its value. Select keeps a
93
- hidden native select for the option value and always renders it, so the label
94
- stays associated and form reset and fieldset state are tracked; `name` alone
95
- decides whether the control is submitted.
96
- - Status line statuses: `success`, `danger`, `info`.
97
- - Alert statuses: `danger`, `info`. Only the border changes with status; the CSS
98
- keeps the alert mark danger-colored.
99
- - Toast status: `success` only. Status line, alert, and toast types are exported
100
- from `/status`, but intentionally do not share an interchangeable status union.
101
-
102
- Native-only components such as checkbox, input, and the plain `.sb-select`
103
- pattern do not need shared custom options. Typography classes and the progress
104
- CSS custom property remain part of the CSS API, not this package.
105
-
106
- ## Migration from the class-map contracts
107
-
108
- Use `buttonDefaults`, `badgeDefaults`, `cardDefaults`, and `toastDefaults` instead
109
- of the corresponding `*Contract.defaults`. Use CSS class and attribute names
110
- directly in adapters. Class-only contracts and their subpaths have been removed.
111
- Existing option type names are unchanged.
112
-
113
- ## Verification
55
+ Types are erased at runtime. Only the `*Defaults` constants are runtime exports — there are no allowed-value arrays without a runtime use case.
114
56
 
115
- ```sh
116
- pnpm --filter @simple-base/contracts typecheck
117
- pnpm --filter @simple-base/contracts build
118
- ```
57
+ ### Values
58
+
59
+ - **Button variants:** `primary`, `secondary`, `tertiary`, `ghost`, `danger`, `danger-subtle`. **Sizes:** `small`, `medium`, `large`. Apply the default attributes explicitly — the bare CSS class is not identical to every default variant rule.
60
+ - **Badge variants:** `default`, `success`, `danger`, `warning`, `info`, `accent`, `command`, `outline`, `muted`. **Sizes:** `small`, `medium`.
61
+ - **Card variants:** `flat`, `rule`. Omit `variant` for the base card; there is no explicit `default` variant. `padding` is boolean and maps to `data-padding="true"` when enabled.
62
+ - **Table cell variants:** `code`, `number`.
63
+ - **Statuses are deliberately not interchangeable.** Status lines use `success`, `danger`, `info`. Alerts use `danger`, `info` — only the border changes with status. Toasts use `success` only. All three are exported from `/status`.
64
+
65
+ ### Select and Combobox
66
+
67
+ `SelectOption` and `ComboboxOption` both contain `label`, a unique `value`, and optional `disabled`.
68
+
69
+ `SelectOptions` and `ComboboxOptions` define the shared root API:
70
+
71
+ | Prop | Required | Description |
72
+ | --------------- | -------- | --------------------------------------------------------------------------------------------------------------------------- |
73
+ | `id` | yes | Unique identifier for the instance. |
74
+ | `label` | yes | Visible label text. |
75
+ | `options` | yes | The option list. |
76
+ | `onValueChange` | yes | Called with the selected option's string value, or `""` when selection is cleared. |
77
+ | `placeholder` | no | Rendered in place of the value text until something is selected. |
78
+ | `value` | no | Controlled counterpart of `onValueChange`. `""` means no selection; omitting `value` leaves it uncontrolled. |
79
+ | `disabled` | no | Dims and blocks the field. |
80
+ | `invalid` | no | Switches the border and focus ring to the danger tokens. |
81
+ | `required` | no | Adds the label marker. |
82
+ | `name` | no | See below — semantics differ per component. |
83
+ | `placement` | no | Shared `top`/`bottom` union with `-start` and `-end` variants; deliberately narrower than an adapter's positioning options. |
84
+ | `onOpenChange` | no | Reports popup visibility, for lazy loading and analytics. |
85
+
86
+ Adapters must treat `""` as a controlled empty selection, not as uncontrolled.
87
+
88
+ The two option lists stay independent so each adapter can evolve its own surface.
89
+
90
+ **`name` differs per component.** Combobox applies it to the visible input, so the submitted value is the option _label_. Select keeps a hidden native select for the option _value_ and always renders it, so the label stays associated and form reset and fieldset state are tracked — `name` alone decides whether the control is submitted.
91
+
92
+ ## What stays in adapters
93
+
94
+ Share framework-neutral configuration and value callbacks. Children, refs, framework-specific DOM events, native element prop interfaces, internal context, and accessibility implementation belong to the adapter.
95
+
96
+ Adapters compose shared options with their framework's native element props, apply defaults when options are omitted, and emit the CSS classes and attributes directly. There are no class-name maps, attribute-name maps, CSS-property maps, or class-only contracts.
97
+
98
+ Native-only components — checkbox, input, and the plain `.sb-select` pattern — have no shared custom options. Typography classes and the progress CSS custom property are part of the CSS package's API, not this one.
99
+
100
+ ## Links
101
+
102
+ - [Repository](https://github.com/redasalmi/simple-base)
103
+ - [Styles and selector API](https://www.npmjs.com/package/@simple-base/css)
104
+ - [Design tokens](https://www.npmjs.com/package/@simple-base/tokens)
105
+ - [Solid components](https://www.npmjs.com/package/@simple-base/solid)
106
+
107
+ ## License
119
108
 
120
- These commands check the shared types and build the runtime defaults and type
121
- declarations.
109
+ [MIT](https://github.com/redasalmi/simple-base/blob/main/LICENSE)
package/package.json CHANGED
@@ -1,7 +1,12 @@
1
1
  {
2
2
  "name": "@simple-base/contracts",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/redasalmi/simple-base.git",
8
+ "directory": "packages/contracts"
9
+ },
5
10
  "files": [
6
11
  "dist"
7
12
  ],