@smartyweb/ui 1.0.3 → 1.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.
package/README.md CHANGED
@@ -8,6 +8,7 @@ Shared React component library consumed by multiple Next.js microservices via pr
8
8
  - Vite (outputs ESM + CJS + types to `dist/`)
9
9
  - Storybook v10 for component development and documentation
10
10
  - Changesets for versioning and changelogs
11
+ - Style Dictionary v4 for design token transformation
11
12
 
12
13
  ## Getting Started
13
14
 
@@ -21,12 +22,22 @@ npm install
21
22
  npm run storybook
22
23
  ```
23
24
 
25
+ This also runs `node sd.config.js` first to generate CSS tokens from `tokens.json`.
26
+
24
27
  ### Build
25
28
 
26
29
  ```bash
27
30
  npm run build
28
31
  ```
29
32
 
33
+ ### Tokens only
34
+
35
+ ```bash
36
+ npm run tokens
37
+ ```
38
+
39
+ Regenerates `src/styles/_tokens.generated.scss` from `tokens.json` without building or starting Storybook.
40
+
30
41
  ## Usage
31
42
 
32
43
  Install the package in your consuming app:
@@ -44,23 +55,61 @@ import "@smartyweb/ui/styles.css";
44
55
  Then import components:
45
56
 
46
57
  ```js
47
- import { Button } from "@smartyweb/ui";
58
+ import { H1, Paragraph } from "@smartyweb/ui";
59
+ ```
60
+
61
+ ### Font Setup
62
+
63
+ This library does not bundle fonts. Consumers are responsible for loading fonts and exposing them as CSS custom properties. The library reads these three variables:
64
+
65
+ | CSS variable | Font | Used by |
66
+ | ------------------- | ------------ | --------------------------------- |
67
+ | `--ui-font-primary` | TT Hoves Pro | All heading and button components |
68
+ | `--ui-font-body` | Inter | Body and paragraph components |
69
+ | `--ui-font-code` | Hack | Code component |
70
+
71
+ In a Next.js app using `next/font/local`, set these on the root element:
72
+
73
+ ```tsx
74
+ // app/layout.tsx
75
+ import localFont from "next/font/local";
76
+
77
+ const ttHovesPro = localFont({
78
+ src: [...],
79
+ variable: "--font-tthoves",
80
+ });
81
+
82
+ export default function RootLayout({ children }) {
83
+ return (
84
+ <html className={ttHovesPro.variable}>
85
+ <body style={{
86
+ "--ui-font-primary": "var(--font-tthoves, 'TT Hoves Pro', system-ui, sans-serif)",
87
+ }}>
88
+ {children}
89
+ </body>
90
+ </html>
91
+ );
92
+ }
48
93
  ```
49
94
 
95
+ If a variable is not set, components fall back to `system-ui` (headings/body) or `monospace` (code).
96
+
50
97
  ## Project Structure
51
98
 
52
99
  ```
100
+ sd.config.js # Style Dictionary config — tokens.json → _tokens.generated.scss
101
+ tokens.json # Designer-owned, synced from Tokens Studio (Figma plugin)
53
102
  src/
54
- components/
103
+ text/
55
104
  ComponentName/
56
105
  ComponentName.tsx # "use client" at top
57
- ComponentName.module.scss
106
+ ComponentName.module.scss # uses var(--token-*) CSS custom properties
58
107
  ComponentName.stories.tsx
59
108
  index.ts # named export
60
109
  index.ts # barrel export
61
110
  styles/
62
- _variables.scss
63
- _mixins.scss
111
+ _variables.scss # SCSS variables (fonts, weights, breakpoints, font-feature-settings)
112
+ _tokens.generated.scss # Auto-generated by sd.config.js — do not edit manually
64
113
  global.scss
65
114
  index.ts # main entry point
66
115
  ```
@@ -69,6 +118,17 @@ src/
69
118
 
70
119
  This package uses [Changesets](https://github.com/changesets/changesets) for versioning and changelog management.
71
120
 
121
+ ### Semver policy
122
+
123
+ | Change type | Bump |
124
+ | -------------------------------------------------------------------------- | ------- |
125
+ | Token value changes (e.g. heading size goes from 64px → 60px) | `patch` |
126
+ | New CSS custom property names added (new tokens consumers could reference) | `minor` |
127
+ | New components added | `minor` |
128
+ | Removed components, renamed props, or changed component API | `major` |
129
+
130
+ Visual changes (token values) are always `patch` — semver communicates API stability, not pixel perfection.
131
+
72
132
  ### Step 1 — On your feature branch
73
133
 
74
134
  Create a changeset to describe the change and bump type:
@@ -80,7 +140,7 @@ npm run changeset
80
140
  This opens an interactive prompt:
81
141
 
82
142
  1. **Which packages changed?** — select `@smartyweb/ui`
83
- 2. **Bump type?** — `patch` for fixes/styles, `minor` for new features, `major` for breaking changes
143
+ 2. **Bump type?** — see semver policy above
84
144
  3. **Summary?** — plain English description (goes into the changelog)
85
145
 
86
146
  Then apply the version bump immediately on the same branch:
@@ -131,6 +191,50 @@ Two secured repository variables must be configured under **Bitbucket repo → S
131
191
 
132
192
  Mark both as **Secured** so they are masked in logs.
133
193
 
194
+ ## Design Tokens
195
+
196
+ Design tokens flow from Figma → code via this pipeline:
197
+
198
+ 1. **Designer** makes changes in Tokens Studio (Figma plugin) and syncs to the `design/tokens-update` branch
199
+ 2. **CI** (Bitbucket Pipelines) runs `npm run tokens` on push, regenerates `src/styles/_tokens.generated.scss`, and commits the diff automatically
200
+ 3. **Developer** opens a PR from `design/tokens-update` → `master`, runs `npx changeset add` on the branch, and merges after review
201
+ 4. **Build** on `master` picks up the updated tokens and publishes a new npm version
202
+
203
+ ### Reviewing a token PR
204
+
205
+ When reviewing a `design/tokens-update` PR, check:
206
+
207
+ - The `_tokens.generated.scss` diff — values should match the designer's intent in Figma
208
+ - Spot-check affected components in Storybook (deployed on Vercel, or run `npm run storybook` locally)
209
+ - Confirm a changeset file is present in `.changeset/` before merging
210
+
211
+ A changeset must be committed to the branch before the PR is merged. The developer opening the PR is responsible for this — the pipeline cannot do it automatically because bump type and description require human input.
212
+
213
+ `sd.config.js` reads only the `Responsive/Desktop`, `Responsive/Tablet`, and `Responsive/Mobile` token sets, outputting ~99 CSS custom properties like:
214
+
215
+ ```css
216
+ :root {
217
+ --h1-desktop-font-size: 64px;
218
+ --h1-desktop-line-height: 64px;
219
+ --h1-desktop-letter-spacing: -0.02em;
220
+ /* ... */
221
+ }
222
+ ```
223
+
224
+ Text components consume these via `var(--{component}-{breakpoint}-{property})`. Font families, weights, and OpenType feature settings remain as SCSS variables in `_variables.scss`.
225
+
226
+ Note: tablet CSS custom properties are generated but components intentionally do not use them. Components apply desktop values down to 768px, then switch to mobile. Tablet tokens are kept in `tokens.json` as source data for the planned fluid typography migration (see Roadmap).
227
+
228
+ ## Roadmap
229
+
230
+ ### Fluid typography
231
+
232
+ The current breakpoint approach (desktop / mobile with a hard switch at 768px) will be replaced with fluid typography using CSS `clamp()`. The desktop and mobile token values will become the max and min of the clamp range respectively, scaling continuously across the viewport.
233
+
234
+ The planned implementation: Style Dictionary computes the `clamp()` formula at build time (it has access to the raw numbers), outputting a single token per property (e.g. `--h1-font-size: clamp(44px, ..., 64px)`) instead of the current per-breakpoint triplets. Component SCSS becomes a single `font-size: var(--h1-font-size)` with no media queries.
235
+
236
+ The tablet token set in `tokens.json` will be retired from the Style Dictionary transform when this ships.
237
+
134
238
  ## Architecture
135
239
 
136
240
  - **Component library only** — no routing, no pages, no app logic.
@@ -138,3 +242,4 @@ Mark both as **Secured** so they are masked in logs.
138
242
  - **CSS is compiled to a single file at build time.** No runtime CSS injection.
139
243
  - **React is a peerDependency**, not bundled.
140
244
  - **Stories are co-located with components.**
245
+ - **`_tokens.generated.scss` is committed** so token changes are visible in PR diffs, but never edit it manually — always regenerate via `npm run tokens`.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),o="_hExtra_zekit_1",a={hExtra:o};function c({as:s="h1",children:t,className:n}){const r=[a.hExtra,n].filter(Boolean).join(" ");return e.jsx(s,{className:r,children:t})}const h="_h1_1w27n_1",i={h1:h};function l({children:s,className:t}){return e.jsx("h1",{className:`${i.h1}${t?` ${t}`:""}`,children:s})}exports.H1=l;exports.HExtra=c;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),e="_hExtra_dx1fb_1",c={hExtra:e};function l({as:a="h1",children:s,className:t}){const n=[c.hExtra,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const r="_h1_iuejz_1",i={h1:r};function u({children:a,className:s}){return o.jsx("h1",{className:`${i.h1}${s?` ${s}`:""}`,children:a})}const p="_h2_1i98w_1",m={h2:p};function _({as:a="h2",children:s,className:t}){const n=[m.h2,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const h="_h3_wip1f_1",f={h3:h};function j({as:a="h3",children:s,className:t}){const n=[f.h3,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const y="_h4_thwwf_1",d={h4:y};function N({as:a="h4",children:s,className:t}){const n=[d.h4,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const g="_h5_zem0s_1",x={h5:g};function B({as:a="h5",children:s,className:t}){const n=[x.h5,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const b="_h6_py9o3_1",L={h6:b};function $({as:a="h6",children:s,className:t}){const n=[L.h6,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const H="_paragraph_6mdxp_1",S={paragraph:H};function C({as:a="p",children:s,className:t}){const n=[S.paragraph,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const M="_bodyLarge_zgxpr_1",E={bodyLarge:M};function U({as:a="p",children:s,className:t}){const n=[E.bodyLarge,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const z="_bodySmall_izgxi_1",w={bodySmall:z};function P({as:a="p",children:s,className:t}){const n=[w.bodySmall,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const k="_buttonLarge_1kib2_1",q={buttonLarge:k};function v({as:a="span",children:s,className:t}){const n=[q.buttonLarge,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const O="_buttonSmall_1ga6z_1",R={buttonSmall:O};function T({as:a="span",children:s,className:t}){const n=[R.buttonSmall,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const A="_captionLarge_keyl9_1",D={captionLarge:A};function F({as:a="span",children:s,className:t}){const n=[D.captionLarge,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const G="_captionMedium_9rjdy_1",I={captionMedium:G};function J({as:a="span",children:s,className:t}){const n=[I.captionMedium,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const K="_captionUppercase_15jnh_1",Q={captionUppercase:K};function V({as:a="span",children:s,className:t}){const n=[Q.captionUppercase,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}const W="_code_1o5oi_1",X={code:W};function Y({as:a="code",children:s,className:t}){const n=[X.code,t].filter(Boolean).join(" ");return o.jsx(a,{className:n,children:s})}exports.BodyLarge=U;exports.BodySmall=P;exports.ButtonLarge=v;exports.ButtonSmall=T;exports.CaptionLarge=F;exports.CaptionMedium=J;exports.CaptionUppercase=V;exports.Code=Y;exports.H1=u;exports.H2=_;exports.H3=j;exports.H4=N;exports.H5=B;exports.H6=$;exports.HExtra=l;exports.Paragraph=C;
package/dist/index.js CHANGED
@@ -1,18 +1,130 @@
1
- import { jsx as n } from "react/jsx-runtime";
2
- const a = "_hExtra_zekit_1", e = {
3
- hExtra: a
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ const e = "_hExtra_dx1fb_1", c = {
3
+ hExtra: e
4
4
  };
5
- function i({ as: s = "h1", children: t, className: o }) {
6
- const r = [e.hExtra, o].filter(Boolean).join(" ");
7
- return /* @__PURE__ */ n(s, { className: r, children: t });
5
+ function A({ as: a = "h1", children: s, className: n }) {
6
+ const o = [c.hExtra, n].filter(Boolean).join(" ");
7
+ return /* @__PURE__ */ t(a, { className: o, children: s });
8
8
  }
9
- const h = "_h1_1w27n_1", c = {
10
- h1: h
9
+ const l = "_h1_iuejz_1", r = {
10
+ h1: l
11
11
  };
12
- function l({ children: s, className: t }) {
13
- return /* @__PURE__ */ n("h1", { className: `${c.h1}${t ? ` ${t}` : ""}`, children: s });
12
+ function D({ children: a, className: s }) {
13
+ return /* @__PURE__ */ t("h1", { className: `${r.h1}${s ? ` ${s}` : ""}`, children: a });
14
+ }
15
+ const i = "_h2_1i98w_1", m = {
16
+ h2: i
17
+ };
18
+ function F({ as: a = "h2", children: s, className: n }) {
19
+ const o = [m.h2, n].filter(Boolean).join(" ");
20
+ return /* @__PURE__ */ t(a, { className: o, children: s });
21
+ }
22
+ const p = "_h3_wip1f_1", u = {
23
+ h3: p
24
+ };
25
+ function G({ as: a = "h3", children: s, className: n }) {
26
+ const o = [u.h3, n].filter(Boolean).join(" ");
27
+ return /* @__PURE__ */ t(a, { className: o, children: s });
28
+ }
29
+ const _ = "_h4_thwwf_1", h = {
30
+ h4: _
31
+ };
32
+ function I({ as: a = "h4", children: s, className: n }) {
33
+ const o = [h.h4, n].filter(Boolean).join(" ");
34
+ return /* @__PURE__ */ t(a, { className: o, children: s });
35
+ }
36
+ const f = "_h5_zem0s_1", N = {
37
+ h5: f
38
+ };
39
+ function J({ as: a = "h5", children: s, className: n }) {
40
+ const o = [N.h5, n].filter(Boolean).join(" ");
41
+ return /* @__PURE__ */ t(a, { className: o, children: s });
42
+ }
43
+ const y = "_h6_py9o3_1", d = {
44
+ h6: y
45
+ };
46
+ function K({ as: a = "h6", children: s, className: n }) {
47
+ const o = [d.h6, n].filter(Boolean).join(" ");
48
+ return /* @__PURE__ */ t(a, { className: o, children: s });
49
+ }
50
+ const g = "_paragraph_6mdxp_1", b = {
51
+ paragraph: g
52
+ };
53
+ function O({ as: a = "p", children: s, className: n }) {
54
+ const o = [b.paragraph, n].filter(Boolean).join(" ");
55
+ return /* @__PURE__ */ t(a, { className: o, children: s });
56
+ }
57
+ const j = "_bodyLarge_zgxpr_1", B = {
58
+ bodyLarge: j
59
+ };
60
+ function Q({ as: a = "p", children: s, className: n }) {
61
+ const o = [B.bodyLarge, n].filter(Boolean).join(" ");
62
+ return /* @__PURE__ */ t(a, { className: o, children: s });
63
+ }
64
+ const $ = "_bodySmall_izgxi_1", L = {
65
+ bodySmall: $
66
+ };
67
+ function R({ as: a = "p", children: s, className: n }) {
68
+ const o = [L.bodySmall, n].filter(Boolean).join(" ");
69
+ return /* @__PURE__ */ t(a, { className: o, children: s });
70
+ }
71
+ const x = "_buttonLarge_1kib2_1", S = {
72
+ buttonLarge: x
73
+ };
74
+ function T({ as: a = "span", children: s, className: n }) {
75
+ const o = [S.buttonLarge, n].filter(Boolean).join(" ");
76
+ return /* @__PURE__ */ t(a, { className: o, children: s });
77
+ }
78
+ const H = "_buttonSmall_1ga6z_1", z = {
79
+ buttonSmall: H
80
+ };
81
+ function V({ as: a = "span", children: s, className: n }) {
82
+ const o = [z.buttonSmall, n].filter(Boolean).join(" ");
83
+ return /* @__PURE__ */ t(a, { className: o, children: s });
84
+ }
85
+ const E = "_captionLarge_keyl9_1", M = {
86
+ captionLarge: E
87
+ };
88
+ function W({ as: a = "span", children: s, className: n }) {
89
+ const o = [M.captionLarge, n].filter(Boolean).join(" ");
90
+ return /* @__PURE__ */ t(a, { className: o, children: s });
91
+ }
92
+ const U = "_captionMedium_9rjdy_1", w = {
93
+ captionMedium: U
94
+ };
95
+ function X({ as: a = "span", children: s, className: n }) {
96
+ const o = [w.captionMedium, n].filter(Boolean).join(" ");
97
+ return /* @__PURE__ */ t(a, { className: o, children: s });
98
+ }
99
+ const C = "_captionUppercase_15jnh_1", k = {
100
+ captionUppercase: C
101
+ };
102
+ function Y({ as: a = "span", children: s, className: n }) {
103
+ const o = [k.captionUppercase, n].filter(Boolean).join(" ");
104
+ return /* @__PURE__ */ t(a, { className: o, children: s });
105
+ }
106
+ const P = "_code_1o5oi_1", q = {
107
+ code: P
108
+ };
109
+ function Z({ as: a = "code", children: s, className: n }) {
110
+ const o = [q.code, n].filter(Boolean).join(" ");
111
+ return /* @__PURE__ */ t(a, { className: o, children: s });
14
112
  }
15
113
  export {
16
- l as H1,
17
- i as HExtra
114
+ Q as BodyLarge,
115
+ R as BodySmall,
116
+ T as ButtonLarge,
117
+ V as ButtonSmall,
118
+ W as CaptionLarge,
119
+ X as CaptionMedium,
120
+ Y as CaptionUppercase,
121
+ Z as Code,
122
+ D as H1,
123
+ F as H2,
124
+ G as H3,
125
+ I as H4,
126
+ J as H5,
127
+ K as H6,
128
+ A as HExtra,
129
+ O as Paragraph
18
130
  };
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface BodyLargeProps {
3
+ as?: "p" | "div" | "span";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function BodyLarge({ as: Tag, children, className }: BodyLargeProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { BodyLarge } from './BodyLarge';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface BodySmallProps {
3
+ as?: "p" | "div" | "span";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function BodySmall({ as: Tag, children, className }: BodySmallProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { BodySmall } from './BodySmall';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface ButtonLargeProps {
3
+ as?: "span" | "p" | "div";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function ButtonLarge({ as: Tag, children, className }: ButtonLargeProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { ButtonLarge } from './ButtonLarge';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface ButtonSmallProps {
3
+ as?: "span" | "p" | "div";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function ButtonSmall({ as: Tag, children, className }: ButtonSmallProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { ButtonSmall } from './ButtonSmall';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface CaptionLargeProps {
3
+ as?: "span" | "p" | "div";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function CaptionLarge({ as: Tag, children, className }: CaptionLargeProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { CaptionLarge } from './CaptionLarge';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface CaptionMediumProps {
3
+ as?: "span" | "p" | "div";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function CaptionMedium({ as: Tag, children, className }: CaptionMediumProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { CaptionMedium } from './CaptionMedium';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface CaptionUppercaseProps {
3
+ as?: "span" | "p" | "div";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function CaptionUppercase({ as: Tag, children, className }: CaptionUppercaseProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { CaptionUppercase } from './CaptionUppercase';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface CodeProps {
3
+ as?: "code" | "pre";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function Code({ as: Tag, children, className }: CodeProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { Code } from './Code';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface H2Props {
3
+ as?: "h1" | "h2" | "h3" | "span";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function H2({ as: Tag, children, className }: H2Props): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { H2 } from './H2';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface H3Props {
3
+ as?: "h2" | "h3" | "h4" | "span";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function H3({ as: Tag, children, className }: H3Props): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { H3 } from './H3';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface H4Props {
3
+ as?: "h3" | "h4" | "h5" | "span";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function H4({ as: Tag, children, className }: H4Props): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { H4 } from './H4';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface H5Props {
3
+ as?: "h4" | "h5" | "h6" | "span";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function H5({ as: Tag, children, className }: H5Props): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { H5 } from './H5';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface H6Props {
3
+ as?: "h5" | "h6" | "span";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function H6({ as: Tag, children, className }: H6Props): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { H6 } from './H6';
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface ParagraphProps {
3
+ as?: "p" | "div" | "span";
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare function Paragraph({ as: Tag, children, className }: ParagraphProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { Paragraph } from './Paragraph';
@@ -1,2 +1,16 @@
1
1
  export * from './HExtra';
2
2
  export * from './H1';
3
+ export * from './H2';
4
+ export * from './H3';
5
+ export * from './H4';
6
+ export * from './H5';
7
+ export * from './H6';
8
+ export * from './Paragraph';
9
+ export * from './BodyLarge';
10
+ export * from './BodySmall';
11
+ export * from './ButtonLarge';
12
+ export * from './ButtonSmall';
13
+ export * from './CaptionLarge';
14
+ export * from './CaptionMedium';
15
+ export * from './CaptionUppercase';
16
+ export * from './Code';
package/dist/ui.css CHANGED
@@ -1 +1 @@
1
- ._hExtra_zekit_1{font-family:var(--ui-font-primary);font-weight:600;font-size:96px;line-height:106px;letter-spacing:-.03em;font-feature-settings:"dlig" 1;margin:0}@media(max-width:767px){._hExtra_zekit_1{font-size:56px;line-height:62px;letter-spacing:-.02em}}._h1_1w27n_1{font-family:var(--ui-font-primary);font-weight:500;font-size:64px;line-height:64px;letter-spacing:-.02em;font-feature-settings:"dlig" 1;margin:0}@media(max-width:767px){._h1_1w27n_1{font-size:44px;line-height:44px;letter-spacing:-.01em}}
1
+ :root{--h-extra-desktop-font-size: 6rem;--h-extra-desktop-line-height: 6.625rem;--h-extra-desktop-letter-spacing: -.03em;--h1-desktop-font-size: 4rem;--h1-desktop-line-height: 4rem;--h1-desktop-letter-spacing: -.02em;--h2-desktop-font-size: 3.25rem;--h2-desktop-line-height: 3.5625rem;--h2-desktop-letter-spacing: -.02em;--h3-desktop-font-size: 2.75rem;--h3-desktop-line-height: 3rem;--h3-desktop-letter-spacing: -.02em;--h4-desktop-font-size: 2.25rem;--h4-desktop-line-height: 2.6875rem;--h4-desktop-letter-spacing: -.02em;--h5-desktop-font-size: 1.875rem;--h5-desktop-line-height: 2.0625rem;--h5-desktop-letter-spacing: -.01em;--h6-desktop-font-size: 1.75rem;--h6-desktop-line-height: 1.9375rem;--h6-desktop-letter-spacing: -.01em;--paragraph-desktop-font-size: 1.5rem;--paragraph-desktop-line-height: 2.25rem;--paragraph-desktop-letter-spacing: -.01em;--button-large-desktop-font-size: 1.25rem;--button-large-desktop-line-height: 1.5rem;--button-large-desktop-letter-spacing: -.02em;--body-large-desktop-font-size: 1.25rem;--body-large-desktop-line-height: 1.875rem;--body-large-desktop-letter-spacing: -.02em;--button-small-desktop-font-size: 1.0625rem;--button-small-desktop-line-height: 1.5rem;--button-small-desktop-letter-spacing: -.02em;--body-small-desktop-font-size: 1rem;--body-small-desktop-line-height: 1.5rem;--body-small-desktop-letter-spacing: -.02em;--caption-large-desktop-font-size: 1rem;--caption-large-desktop-line-height: 1.5rem;--caption-large-desktop-letter-spacing: -.02em;--caption-medium-desktop-font-size: .75rem;--caption-medium-desktop-line-height: 1.125rem;--caption-medium-desktop-letter-spacing: -.02em;--caption-uppercase-desktop-font-size: .8125rem;--caption-uppercase-desktop-line-height: 1rem;--caption-uppercase-desktop-letter-spacing: .04em;--code-desktop-font-size: .875rem;--code-desktop-line-height: 1.0625rem;--code-desktop-letter-spacing: 0;--h-extra-tablet-font-size: 6rem;--h-extra-tablet-line-height: 6.625rem;--h-extra-tablet-letter-spacing: -.03em;--h1-tablet-font-size: 4rem;--h1-tablet-line-height: 4rem;--h1-tablet-letter-spacing: -.02em;--h2-tablet-font-size: 3rem;--h2-tablet-line-height: 3.3125rem;--h2-tablet-letter-spacing: -.02em;--h3-tablet-font-size: 2.5rem;--h3-tablet-line-height: 2.75rem;--h3-tablet-letter-spacing: -.02em;--h4-tablet-font-size: 2.25rem;--h4-tablet-line-height: 2.6875rem;--h4-tablet-letter-spacing: -.02em;--h5-tablet-font-size: 2rem;--h5-tablet-line-height: 2.1875rem;--h5-tablet-letter-spacing: -.01em;--h6-tablet-font-size: 1.5rem;--h6-tablet-line-height: 1.625rem;--h6-tablet-letter-spacing: -.01em;--paragraph-tablet-font-size: 1.375rem;--paragraph-tablet-line-height: 2.0625rem;--paragraph-tablet-letter-spacing: -.01em;--button-large-tablet-font-size: 1.125rem;--button-large-tablet-line-height: 1.5rem;--button-large-tablet-letter-spacing: -.02em;--body-large-tablet-font-size: 1.125rem;--body-large-tablet-line-height: 1.6875rem;--body-large-tablet-letter-spacing: -.02em;--button-small-tablet-font-size: 1rem;--button-small-tablet-line-height: 1.5rem;--button-small-tablet-letter-spacing: -.02em;--body-small-tablet-font-size: 1rem;--body-small-tablet-line-height: 1.5rem;--body-small-tablet-letter-spacing: -.02em;--caption-large-tablet-font-size: 1rem;--caption-large-tablet-line-height: 1.5rem;--caption-large-tablet-letter-spacing: -.02em;--caption-medium-tablet-font-size: .75rem;--caption-medium-tablet-line-height: 1.125rem;--caption-medium-tablet-letter-spacing: -.02em;--caption-uppercase-tablet-font-size: .8125rem;--caption-uppercase-tablet-line-height: 1rem;--caption-uppercase-tablet-letter-spacing: .04em;--code-tablet-font-size: .875rem;--code-tablet-line-height: 1.0625rem;--code-tablet-letter-spacing: 0;--h-extra-mobile-font-size: 3.5rem;--h-extra-mobile-line-height: 3.875rem;--h-extra-mobile-letter-spacing: -.02em;--h1-mobile-font-size: 2.75rem;--h1-mobile-line-height: 2.75rem;--h1-mobile-letter-spacing: -.01em;--h2-mobile-font-size: 2.5rem;--h2-mobile-line-height: 2.75rem;--h2-mobile-letter-spacing: -.01em;--h3-mobile-font-size: 2.25rem;--h3-mobile-line-height: 2.5rem;--h3-mobile-letter-spacing: -.01em;--h4-mobile-font-size: 2rem;--h4-mobile-line-height: 2.625rem;--h4-mobile-letter-spacing: -.01em;--h5-mobile-font-size: 1.375rem;--h5-mobile-line-height: 1.5rem;--h5-mobile-letter-spacing: -.01em;--h6-mobile-font-size: 1.25rem;--h6-mobile-line-height: 1.375rem;--h6-mobile-letter-spacing: -.01em;--paragraph-mobile-font-size: 1.125rem;--paragraph-mobile-line-height: 1.6875rem;--paragraph-mobile-letter-spacing: -.01em;--button-large-mobile-font-size: 1rem;--button-large-mobile-line-height: 1.5rem;--button-large-mobile-letter-spacing: -.01em;--body-large-mobile-font-size: 1rem;--body-large-mobile-line-height: 1.5rem;--body-large-mobile-letter-spacing: -.01em;--button-small-mobile-font-size: .875rem;--button-small-mobile-line-height: 1.5rem;--button-small-mobile-letter-spacing: -.01em;--body-small-mobile-font-size: .875rem;--body-small-mobile-line-height: 1.3125rem;--body-small-mobile-letter-spacing: -.01em;--caption-large-mobile-font-size: 1rem;--caption-large-mobile-line-height: 1.5rem;--caption-large-mobile-letter-spacing: -.02em;--caption-medium-mobile-font-size: .75rem;--caption-medium-mobile-line-height: 1.125rem;--caption-medium-mobile-letter-spacing: -.02em;--caption-uppercase-mobile-font-size: .8125rem;--caption-uppercase-mobile-line-height: 1rem;--caption-uppercase-mobile-letter-spacing: .04em;--code-mobile-font-size: .75rem;--code-mobile-line-height: 1.0625rem;--code-mobile-letter-spacing: 0}._hExtra_dx1fb_1{font-family:var(--ui-font-primary);font-weight:600;font-size:var(--h-extra-desktop-font-size);line-height:var(--h-extra-desktop-line-height);letter-spacing:var(--h-extra-desktop-letter-spacing);font-feature-settings:"dlig" 1,"ss01" 1,"ss02" 1,"ss04" 1;margin:0}@media(max-width:767px){._hExtra_dx1fb_1{font-size:var(--h-extra-mobile-font-size);line-height:var(--h-extra-mobile-line-height);letter-spacing:var(--h-extra-mobile-letter-spacing)}}._h1_iuejz_1{font-family:var(--ui-font-primary);font-weight:500;font-size:var(--h1-desktop-font-size);line-height:var(--h1-desktop-line-height);letter-spacing:var(--h1-desktop-letter-spacing);font-feature-settings:"dlig" 1,"ss01" 1,"ss02" 1,"ss04" 1;margin:0}@media(max-width:767px){._h1_iuejz_1{font-size:var(--h1-mobile-font-size);line-height:var(--h1-mobile-line-height);letter-spacing:var(--h1-mobile-letter-spacing)}}._h2_1i98w_1{font-family:var(--ui-font-primary);font-weight:500;font-size:var(--h2-desktop-font-size);line-height:var(--h2-desktop-line-height);letter-spacing:var(--h2-desktop-letter-spacing);font-feature-settings:"dlig" 1,"ss01" 1,"ss02" 1,"ss04" 1;margin:0}@media(max-width:1439px){._h2_1i98w_1{font-size:var(--h2-tablet-font-size);line-height:var(--h2-tablet-line-height)}}@media(max-width:767px){._h2_1i98w_1{font-size:var(--h2-mobile-font-size);line-height:var(--h2-mobile-line-height);letter-spacing:var(--h2-mobile-letter-spacing)}}._h3_wip1f_1{font-family:var(--ui-font-primary);font-weight:500;font-size:var(--h3-desktop-font-size);line-height:var(--h3-desktop-line-height);letter-spacing:var(--h3-desktop-letter-spacing);font-feature-settings:"dlig" 1,"ss01" 1,"ss02" 1,"ss04" 1;margin:0}@media(max-width:1439px){._h3_wip1f_1{font-size:var(--h3-tablet-font-size);line-height:var(--h3-tablet-line-height)}}@media(max-width:767px){._h3_wip1f_1{font-size:var(--h3-mobile-font-size);line-height:var(--h3-mobile-line-height);letter-spacing:var(--h3-mobile-letter-spacing)}}._h4_thwwf_1{font-family:var(--ui-font-primary);font-weight:500;font-size:var(--h4-desktop-font-size);line-height:var(--h4-desktop-line-height);letter-spacing:var(--h4-desktop-letter-spacing);font-feature-settings:"dlig" 1,"ss01" 1,"ss02" 1,"ss04" 1;margin:0}@media(max-width:767px){._h4_thwwf_1{font-size:var(--h4-mobile-font-size);line-height:var(--h4-mobile-line-height);letter-spacing:var(--h4-mobile-letter-spacing)}}._h5_zem0s_1{font-family:var(--ui-font-primary);font-weight:500;font-size:var(--h5-desktop-font-size);line-height:var(--h5-desktop-line-height);letter-spacing:var(--h5-desktop-letter-spacing);font-feature-settings:"dlig" 1,"ss01" 1,"ss02" 1,"ss04" 1;margin:0}@media(max-width:1439px){._h5_zem0s_1{font-size:var(--h5-tablet-font-size);line-height:var(--h5-tablet-line-height)}}@media(max-width:767px){._h5_zem0s_1{font-size:var(--h5-mobile-font-size);line-height:var(--h5-mobile-line-height)}}._h6_py9o3_1{font-family:var(--ui-font-primary);font-weight:500;font-size:var(--h6-desktop-font-size);line-height:var(--h6-desktop-line-height);letter-spacing:var(--h6-desktop-letter-spacing);font-feature-settings:"dlig" 1,"ss01" 1,"ss02" 1,"ss04" 1;margin:0}@media(max-width:1439px){._h6_py9o3_1{font-size:var(--h6-tablet-font-size);line-height:var(--h6-tablet-line-height)}}@media(max-width:767px){._h6_py9o3_1{font-size:var(--h6-mobile-font-size);line-height:var(--h6-mobile-line-height)}}._paragraph_6mdxp_1{font-family:var(--ui-font-primary);font-weight:500;font-size:var(--paragraph-desktop-font-size);line-height:var(--paragraph-desktop-line-height);letter-spacing:var(--paragraph-desktop-letter-spacing);font-feature-settings:"ss01" 1,"ss02" 1,"ss04" 1;margin:0}@media(max-width:1439px){._paragraph_6mdxp_1{font-size:var(--paragraph-tablet-font-size);line-height:var(--paragraph-tablet-line-height)}}@media(max-width:767px){._paragraph_6mdxp_1{font-size:var(--paragraph-mobile-font-size);line-height:var(--paragraph-mobile-line-height)}}._bodyLarge_zgxpr_1{font-family:var(--ui-font-primary);font-weight:400;font-size:var(--body-large-desktop-font-size);line-height:var(--body-large-desktop-line-height);letter-spacing:var(--body-large-desktop-letter-spacing);font-feature-settings:"dlig" 1;margin:0}@media(max-width:1439px){._bodyLarge_zgxpr_1{font-size:var(--body-large-tablet-font-size);line-height:var(--body-large-tablet-line-height)}}@media(max-width:767px){._bodyLarge_zgxpr_1{font-size:var(--body-large-mobile-font-size);line-height:var(--body-large-mobile-line-height);letter-spacing:var(--body-large-mobile-letter-spacing)}}._bodySmall_izgxi_1{font-family:var(--ui-font-primary);font-weight:400;font-size:var(--body-small-desktop-font-size);line-height:var(--body-small-desktop-line-height);letter-spacing:var(--body-small-desktop-letter-spacing);font-feature-settings:"dlig" 1;margin:0}@media(max-width:767px){._bodySmall_izgxi_1{font-size:var(--body-small-mobile-font-size);line-height:var(--body-small-mobile-line-height);letter-spacing:var(--body-small-mobile-letter-spacing)}}._buttonLarge_1kib2_1{font-family:var(--ui-font-body);font-weight:500;font-size:var(--button-large-desktop-font-size);line-height:var(--button-large-desktop-line-height);letter-spacing:var(--button-large-desktop-letter-spacing);font-feature-settings:"dlig" 1}@media(max-width:1439px){._buttonLarge_1kib2_1{font-size:var(--button-large-tablet-font-size)}}@media(max-width:767px){._buttonLarge_1kib2_1{font-family:var(--ui-font-primary);font-size:var(--button-large-mobile-font-size);letter-spacing:var(--button-large-mobile-letter-spacing)}}._buttonSmall_1ga6z_1{font-family:var(--ui-font-body);font-weight:500;font-size:var(--button-small-desktop-font-size);line-height:var(--button-small-desktop-line-height);letter-spacing:var(--button-small-desktop-letter-spacing);font-feature-settings:"dlig" 1}@media(max-width:1439px){._buttonSmall_1ga6z_1{font-size:var(--button-small-tablet-font-size)}}@media(max-width:767px){._buttonSmall_1ga6z_1{font-family:var(--ui-font-primary);font-size:var(--button-small-mobile-font-size);letter-spacing:var(--button-small-mobile-letter-spacing)}}._captionLarge_keyl9_1{font-family:var(--ui-font-body);font-weight:500;font-size:var(--caption-large-desktop-font-size);line-height:var(--caption-large-desktop-line-height);letter-spacing:var(--caption-large-desktop-letter-spacing);font-feature-settings:"dlig" 1}@media(max-width:767px){._captionLarge_keyl9_1{font-family:var(--ui-font-primary)}}._captionMedium_9rjdy_1{font-family:var(--ui-font-body);font-weight:400;font-size:var(--caption-medium-desktop-font-size);line-height:var(--caption-medium-desktop-line-height);letter-spacing:var(--caption-medium-desktop-letter-spacing);font-feature-settings:"dlig" 1}@media(max-width:767px){._captionMedium_9rjdy_1{font-family:var(--ui-font-primary)}}._captionUppercase_15jnh_1{font-family:var(--ui-font-body);font-weight:400;font-size:var(--caption-uppercase-desktop-font-size);line-height:var(--caption-uppercase-desktop-line-height);letter-spacing:var(--caption-uppercase-desktop-letter-spacing);font-feature-settings:"dlig" 1;text-transform:uppercase}@media(max-width:767px){._captionUppercase_15jnh_1{font-family:var(--ui-font-primary)}}._code_1o5oi_1{font-family:var(--ui-font-code);font-weight:400;font-size:var(--code-desktop-font-size);line-height:var(--code-desktop-line-height);letter-spacing:var(--code-desktop-letter-spacing);font-feature-settings:"dlig" 1}@media(max-width:767px){._code_1o5oi_1{font-size:var(--code-mobile-font-size)}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartyweb/ui",
3
- "version": "1.0.3",
3
+ "version": "1.1.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -17,12 +17,14 @@
17
17
  "dist"
18
18
  ],
19
19
  "scripts": {
20
- "build": "vite build",
20
+ "tokens": "node sd.config.js",
21
+ "build": "node sd.config.js && vite build",
21
22
  "typecheck": "tsc --noEmit",
22
23
  "changeset": "changeset",
23
24
  "release": "changeset publish",
24
- "storybook": "storybook dev -p 6006",
25
- "build-storybook": "storybook build"
25
+ "storybook": "node sd.config.js && storybook dev -p 6006",
26
+ "build-storybook": "storybook build",
27
+ "lint": "eslint src --max-warnings 0 && stylelint 'src/**/*.scss'"
26
28
  },
27
29
  "peerDependencies": {
28
30
  "react": "^19.0.0",
@@ -30,16 +32,22 @@
30
32
  },
31
33
  "devDependencies": {
32
34
  "@changesets/cli": "^2.29.8",
33
- "@storybook/react-vite": "^10.2.8",
35
+ "@eslint/js": "^10.0.0",
36
+ "@storybook/react-vite": "^10.2.15",
34
37
  "@types/react": "^19.2.13",
35
38
  "@types/react-dom": "^19.2.3",
36
39
  "@vitejs/plugin-react": "^5.1.3",
40
+ "eslint": "^10.0.0",
37
41
  "prettier": "^3.8.1",
38
42
  "react": "^19.2.4",
39
43
  "react-dom": "^19.2.4",
40
44
  "sass": "^1.97.3",
41
- "storybook": "^10.2.8",
45
+ "storybook": "^10.2.15",
46
+ "style-dictionary": "^4.4.0",
47
+ "stylelint": "^17.5.0",
48
+ "stylelint-config-standard-scss": "^17.0.0",
42
49
  "typescript": "^5.9.3",
50
+ "typescript-eslint": "^8.57.0",
43
51
  "vite": "^7.3.1",
44
52
  "vite-plugin-dts": "^4.5.4"
45
53
  }