create-bestax 3.6.0 → 3.7.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/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +27 -3
- package/package.json +3 -3
- package/templates/skills/bestax-custom-component/SKILL.md +28 -3
- package/templates/skills/bestax-layout-scaffold/SKILL.md +40 -7
- package/templates/skills/bestax-layout-scaffold/examples/landing.tsx +42 -2
- package/templates/skills/bestax-layout-scaffold/references/archetypes.md +35 -3
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,SAAS,EAAE,QAAQ,EAG/B,CAAC;AAEF,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AACpD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,kBAAkB,QAAsB,CAAC;AAEtD,eAAO,MAAM,QAAQ;;;;;;;wCAaQ,MAAM;uCAEP,MAAM;sCACP,MAAM;4CAEA,MAAM;;;;;CAM7B,CAAC;AASX,eAAO,MAAM,WAAW,QAed,CAAC;AAEX,eAAO,MAAM,OAAO;;;;;;CAOV,CAAC;AAOX,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK9D,CAAC;AAKF,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,SAAS,GACpB,aAAa,MAAM,EACnB,8BAA8B,eAAe,KAC5C,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,SAAS,EAAE,QAAQ,EAG/B,CAAC;AAEF,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AACpD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,kBAAkB,QAAsB,CAAC;AAEtD,eAAO,MAAM,QAAQ;;;;;;;wCAaQ,MAAM;uCAEP,MAAM;sCACP,MAAM;4CAEA,MAAM;;;;;CAM7B,CAAC;AASX,eAAO,MAAM,WAAW,QAed,CAAC;AAEX,eAAO,MAAM,OAAO;;;;;;CAOV,CAAC;AAOX,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK9D,CAAC;AAKF,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,SAAS,GACpB,aAAa,MAAM,EACnB,8BAA8B,eAAe,KAC5C,MAgGF,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IAIrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,cAAc,EAAE,WAAW,EA6CvC,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,aAAa,EAAE,WAAW,EA4CtC,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -93,12 +93,36 @@ ${setupLines.join('\n')}
|
|
|
93
93
|
|
|
94
94
|
## House style
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
**Never inline \`style={{}}\`** — the components accept helper props that cover the common
|
|
97
|
+
cases. Before writing \`style\`, translate each declaration with this table:
|
|
98
|
+
|
|
99
|
+
| Inline style you're about to write | Helper props instead |
|
|
100
|
+
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
101
|
+
| \`marginTop: '1rem'\` (any margin/padding) | \`mt="4"\` — \`m\`/\`mt\`/\`mx\`/\`p\`/\`py\`/… scale: \`1\`=0.25rem, \`2\`=0.5rem, \`3\`=0.75rem, \`4\`=1rem, \`5\`=1.5rem, \`6\`=3rem (nearest step) |
|
|
102
|
+
| \`textAlign: 'center'\` | \`textAlign="centered"\` (also \`left\`, \`right\`, \`justified\`) |
|
|
103
|
+
| \`color: '#…'\` | \`textColor\` with the nearest Bulma color: \`primary\`, \`link\`, \`info\`, \`success\`, \`warning\`, \`danger\`, \`white\`, \`black\`, \`grey\` (+ \`grey-light\`, \`grey-dark\`, …) |
|
|
104
|
+
| \`backgroundColor: '#…'\` | \`bgColor\` (same palette) |
|
|
105
|
+
| \`fontSize: …\` | \`textSize="1"\`…\`"7"\` (\`1\` largest) — for headings use \`Title\`/\`SubTitle\` \`size\` |
|
|
106
|
+
| \`fontWeight: …\` | \`textWeight\`: \`light\`, \`normal\`, \`medium\`, \`semibold\`, \`bold\` |
|
|
107
|
+
| \`textTransform\`, italics | \`textTransform\`: \`uppercase\`, \`lowercase\`, \`capitalized\`, \`italic\` |
|
|
108
|
+
| \`display: 'flex'\` + flex properties | same-named props: \`display="flex"\`, \`flexDirection\`, \`justifyContent\`, \`alignItems\`, \`flexWrap\` |
|
|
109
|
+
| \`height: '100%'\` on a flex child | \`flexGrow="1"\` |
|
|
110
|
+
| \`display: 'none'\` | \`visibility="hidden"\`, or responsive \`display*\` props (\`displayMobile\`, \`displayTablet\`, …) |
|
|
111
|
+
|
|
112
|
+
- Spacing, typography, and flex helpers are on every component; \`textColor\`/\`bgColor\` are
|
|
113
|
+
on the content components (\`Box\`, \`Block\`, \`Title\`, \`Content\`, \`Hero\`, \`Card\`, …) — the
|
|
114
|
+
ones with a semantic \`color\` variant (\`Tag\`, \`Tabs\`, \`Panel\`) take \`color\` instead.
|
|
115
|
+
\`Notification\` is the mixed case: it takes \`textColor\`, but its background comes from
|
|
116
|
+
the semantic \`color\` prop, not \`bgColor\`.
|
|
117
|
+
- Flex layouts have no \`gap\` helper — space children with margins (\`Grid\` and \`Columns\`
|
|
99
118
|
take a \`gap\` prop, so prefer that there).
|
|
119
|
+
- No helper matches (e.g. \`maxWidth\`, a one-off gradient)? Add a named class to
|
|
120
|
+
\`src/App.css\` and pass it via \`className\` — still never inline \`style\`.
|
|
100
121
|
- Compose existing components before writing custom CSS; theme via \`Theme\` and \`--bulma-*\`
|
|
101
122
|
variables, never hardcoded colors.
|
|
123
|
+
- \`Navbar.Burger\`/\`Navbar.Menu\` are controlled — wire \`active\` via state on both, and pair
|
|
124
|
+
\`Navbar fixed="top"\` with the \`has-navbar-fixed-top\` class on \`<html>\` (never an inline
|
|
125
|
+
padding offset).
|
|
102
126
|
- There is no test runner or Storybook in this app — don't assume one.
|
|
103
127
|
- \`index.html\`'s \`<title>\` starts as the project name and \`README.md\` is stock template
|
|
104
128
|
boilerplate — once this app has a real identity, set the title (and any meta tags) to match
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-bestax",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.1",
|
|
4
4
|
"description": "Create a new bestax-bulma project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -64,13 +64,13 @@
|
|
|
64
64
|
"@playwright/test": "^1.57.0",
|
|
65
65
|
"@types/fs-extra": "^11.0.4",
|
|
66
66
|
"@types/jest": "^30.0.0",
|
|
67
|
-
"@types/node": "^26.
|
|
67
|
+
"@types/node": "^26.1.1",
|
|
68
68
|
"@types/prompts": "^2.4.9",
|
|
69
69
|
"@types/wait-on": "^5.3.4",
|
|
70
70
|
"jest": "^30.2.0",
|
|
71
71
|
"ts-jest": "^29.4.6",
|
|
72
72
|
"typescript": "^6.0.3",
|
|
73
|
-
"wait-on": "^9.0
|
|
73
|
+
"wait-on": "^9.1.0"
|
|
74
74
|
},
|
|
75
75
|
"publishConfig": {
|
|
76
76
|
"access": "public",
|
|
@@ -101,8 +101,32 @@ free. `references/api.md` documents the helpers.
|
|
|
101
101
|
## Styling ladder — use the lowest rung that works
|
|
102
102
|
|
|
103
103
|
**Rung 1 — helper props only (default).** House rules: never `style={{}}`. Layout with
|
|
104
|
-
`Block`/`Box` and `display="flex"`, `flexDirection`, `alignItems`, `justifyContent`.
|
|
105
|
-
**no `gap` helper** — space children with `m*`/`p*` margins instead
|
|
104
|
+
`Block`/`Box` and `display="flex"`, `flexDirection`, `alignItems`, `justifyContent`. Flex
|
|
105
|
+
layouts have **no `gap` helper** — space children with `m*`/`p*` margins instead (`Grid` and
|
|
106
|
+
`Columns` take a `gap` prop). Before writing `style={{ … }}` anywhere, translate each
|
|
107
|
+
declaration:
|
|
108
|
+
|
|
109
|
+
| Inline style you're about to write | Helper props instead |
|
|
110
|
+
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
111
|
+
| `marginTop: '1rem'` (any margin/padding) | `mt="4"` — `m`/`mt`/`mx`/`p`/`py`/… scale: `1`=0.25rem, `2`=0.5rem, `3`=0.75rem, `4`=1rem, `5`=1.5rem, `6`=3rem (nearest step) |
|
|
112
|
+
| `textAlign: 'center'` | `textAlign="centered"` (also `left`, `right`, `justified`) |
|
|
113
|
+
| `color: '#…'` | `textColor` with the nearest Bulma color: `primary`, `link`, `info`, `success`, `warning`, `danger`, `white`, `black`, `grey` (+ `grey-light`, `grey-dark`, …) |
|
|
114
|
+
| `backgroundColor: '#…'` | `bgColor` (same palette) |
|
|
115
|
+
| `fontSize: …` | `textSize="1"`…`"7"` (`1` largest) — for headings use `Title`/`SubTitle` `size` |
|
|
116
|
+
| `fontWeight: …` | `textWeight`: `light`, `normal`, `medium`, `semibold`, `bold` |
|
|
117
|
+
| `textTransform`, italics | `textTransform`: `uppercase`, `lowercase`, `capitalized`, `italic` |
|
|
118
|
+
| `display: 'flex'` + flex properties | same-named props: `display="flex"`, `flexDirection`, `justifyContent`, `alignItems`, `flexWrap` |
|
|
119
|
+
| `height: '100%'` on a flex child | `flexGrow="1"` |
|
|
120
|
+
| `display: 'none'` | `visibility="hidden"`, or responsive `display*` props (`displayMobile`, `displayTablet`, …) |
|
|
121
|
+
|
|
122
|
+
Spacing, typography, and flex helpers are on every component; `textColor`/`bgColor` are on
|
|
123
|
+
the content components you'll compose with (`Box`, `Block`, `Title`, `Content`, `Card`, …) —
|
|
124
|
+
the ones with a semantic `color` variant (`Tag`, `Tabs`, `Panel`) take `color` instead.
|
|
125
|
+
`Notification` is the mixed case: it takes `textColor`, but its background comes from the
|
|
126
|
+
semantic `color` prop, not `bgColor`.
|
|
127
|
+
|
|
128
|
+
A value with no helper equivalent (`maxWidth: 720`, a one-off gradient) moves you to rung 2 —
|
|
129
|
+
a named class in a stylesheet — never to inline `style`.
|
|
106
130
|
|
|
107
131
|
**Rung 2 — a plain CSS file**, scoped under the component's class, consuming `--bulma-*`
|
|
108
132
|
variables — never literal colors, so `Theme` and dark mode keep working:
|
|
@@ -153,7 +177,8 @@ render, prop→class mapping, helper-prop passthrough (`m="3"` → `m-3`), and t
|
|
|
153
177
|
- [ ] Inventory checked (catalog + bestax.io/docs/api) and the decision surfaced to the user.
|
|
154
178
|
- [ ] All imports from `@allxsmith/bestax-bulma` (no deep/internal paths).
|
|
155
179
|
- [ ] Composition first — existing components + helper props before any CSS.
|
|
156
|
-
- [ ] No inline `style={{}}` anywhere
|
|
180
|
+
- [ ] No inline `style={{}}` anywhere — translate via the rung-1 mapping table; values with
|
|
181
|
+
no helper equivalent get a named class (rung 2).
|
|
157
182
|
- [ ] Lowest sufficient ladder rung (helper props → scoped CSS vars → Sass).
|
|
158
183
|
- [ ] All colors/radii derived from `--bulma-*` variables — no literals.
|
|
159
184
|
- [ ] Renders correctly via `npm run dev`, including dark mode.
|
|
@@ -45,11 +45,15 @@ Centered; a collection of items → Card grid. For mixed requests, pick the domi
|
|
|
45
45
|
`height: 100%` on the card doesn't help — the column's height is auto).
|
|
46
46
|
- Rely on Bulma's responsive defaults: `Columns` sit side by side on tablet and up and stack on
|
|
47
47
|
mobile. Add responsive `size*` props only to tune the breakpoints.
|
|
48
|
-
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
- `Navbar.Burger`/`Navbar.Menu` are **controlled** — wire the same `active` state to both:
|
|
49
|
+
`active` on `Navbar.Menu` shows/hides the mobile menu, while `active` + `onClick` on
|
|
50
|
+
`Navbar.Burger` make the burger toggle it and animate. Left unwired, clicking the burger
|
|
51
|
+
does nothing (no error, silent failure). For a `fixed="top"` `Navbar`, add the
|
|
52
|
+
`has-navbar-fixed-top` class to `<html>` so content is not hidden behind it — the library
|
|
53
|
+
does not do this automatically, and an inline padding offset is not a substitute.
|
|
54
|
+
- **Style with helper props, not inline `style`.** Before writing `style={{ … }}` anywhere,
|
|
55
|
+
translate each declaration with the mapping table below — the helper props cover the common
|
|
56
|
+
cases. Set the app-wide icon library once with `<ConfigProvider iconLibrary="…">` at the root
|
|
53
57
|
rather than `library` on every `<Icon>`.
|
|
54
58
|
- **CTAs on a colored hero must stay legible in both schemes.** On a fixed-color surface
|
|
55
59
|
(`Hero color="primary"`, a dark banner), use **filled** buttons — `color="light"` or
|
|
@@ -59,6 +63,33 @@ color }}`. Set the app-wide icon library once with `<ConfigProvider iconLibrary=
|
|
|
59
63
|
`<Theme isRoot colorMode="light">` — so a visitor's OS dark mode can't flip Bulma's text
|
|
60
64
|
colors out from under the fixed palette (details: the `bestax-theming` skill's contrast rules).
|
|
61
65
|
|
|
66
|
+
## Inline style → helper prop mapping
|
|
67
|
+
|
|
68
|
+
Look up the declaration you were about to inline. The spacing, typography, and flex helpers
|
|
69
|
+
below are on every component; `textColor`/`bgColor` are on the content components you'll
|
|
70
|
+
target (`Box`, `Block`, `Title`, `Content`, `Hero`, `Card`, …) — the ones with a semantic
|
|
71
|
+
`color` variant (`Tag`, `Tabs`, `Panel`) take `color` instead; wrap content in a `Block` if
|
|
72
|
+
you need a text color there. `Notification` is the mixed case: it takes `textColor`, but its
|
|
73
|
+
background comes from the semantic `color` prop, not `bgColor`.
|
|
74
|
+
|
|
75
|
+
| Inline style you're about to write | Helper props instead |
|
|
76
|
+
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
77
|
+
| `marginTop: '1rem'` (any margin/padding) | `mt="4"` — `m`/`mt`/`mx`/`p`/`py`/… scale: `1`=0.25rem, `2`=0.5rem, `3`=0.75rem, `4`=1rem, `5`=1.5rem, `6`=3rem (nearest step) |
|
|
78
|
+
| `textAlign: 'center'` | `textAlign="centered"` (also `left`, `right`, `justified`) |
|
|
79
|
+
| `color: '#…'` | `textColor` with the nearest Bulma color: `primary`, `link`, `info`, `success`, `warning`, `danger`, `white`, `black`, `grey` (+ `grey-light`, `grey-dark`, …) |
|
|
80
|
+
| `backgroundColor: '#…'` | `bgColor` (same palette) |
|
|
81
|
+
| `fontSize: …` | `textSize="1"`…`"7"` (`1` largest) — for headings use `Title`/`SubTitle` `size` |
|
|
82
|
+
| `fontWeight: …` | `textWeight`: `light`, `normal`, `medium`, `semibold`, `bold` |
|
|
83
|
+
| `textTransform`, italics | `textTransform`: `uppercase`, `lowercase`, `capitalized`, `italic` |
|
|
84
|
+
| `display: 'flex'` + flex properties | same-named props: `display="flex"`, `flexDirection`, `justifyContent`, `alignItems`, `flexWrap` |
|
|
85
|
+
| `height: '100%'` on a flex child | `flexGrow="1"` |
|
|
86
|
+
| `display: 'none'` | `visibility="hidden"`, or responsive `display*` props (`displayMobile`, `displayTablet`, …) |
|
|
87
|
+
| `gap: …` in a flex layout | no `gap` helper exists — space children with `m*` margins; `Grid` and `Columns` take a `gap` prop, so prefer those there |
|
|
88
|
+
|
|
89
|
+
No helper matches (e.g. `maxWidth`, a one-off gradient)? Add a named class to the project
|
|
90
|
+
stylesheet (`src/App.css` in a scaffolded app) and pass it via `className` — still never
|
|
91
|
+
inline `style`.
|
|
92
|
+
|
|
62
93
|
## References
|
|
63
94
|
|
|
64
95
|
- `references/layout-components.md` — the layout component inventory: real prop names, types, and
|
|
@@ -69,7 +100,7 @@ color }}`. Set the app-wide icon library once with `<ConfigProvider iconLibrary=
|
|
|
69
100
|
## Examples
|
|
70
101
|
|
|
71
102
|
- `examples/app-shell.tsx` — fixed `Navbar` + sidebar `Menu` + content (dashboard).
|
|
72
|
-
- `examples/landing.tsx` — `Hero` + `Section`s + `Footer`.
|
|
103
|
+
- `examples/landing.tsx` — fixed `Navbar` (controlled burger) + `Hero` + `Section`s + `Footer`.
|
|
73
104
|
- `examples/centered.tsx` — centered single column (auth/settings).
|
|
74
105
|
- `examples/card-grid.tsx` — multiline `Columns` of `Card`s (catalog).
|
|
75
106
|
- `examples/content-page.tsx` — hero + feature cards + CTA styled with helper props (no inline
|
|
@@ -82,7 +113,9 @@ color }}`. Set the app-wide icon library once with `<ConfigProvider iconLibrary=
|
|
|
82
113
|
- [ ] Use `Grid`/`Cell` for uniform grids (equal heights per row, free); `Columns`/`Column`
|
|
83
114
|
for proportional or per-breakpoint side-by-side layout — with the flex recipe when its
|
|
84
115
|
cards must match height.
|
|
116
|
+
- [ ] Wire `active` state to **both** `Navbar.Burger` and `Navbar.Menu` (they are controlled).
|
|
85
117
|
- [ ] For a fixed navbar, add `has-navbar-fixed-top` to `<html>`.
|
|
86
118
|
- [ ] Do not use `Tile` — it is not shipped.
|
|
87
|
-
- [ ] Style with helper props
|
|
119
|
+
- [ ] Style with helper props, not inline `style` — translate via the mapping table; values
|
|
120
|
+
with no helper get a named class in the stylesheet, never `style={{}}`.
|
|
88
121
|
- [ ] Set the icon library once via `<ConfigProvider iconLibrary="…">` at the root.
|
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
// Marketing / landing page — Hero + stacked Sections + Footer.
|
|
1
|
+
// Marketing / landing page — fixed top Navbar + Hero + stacked Sections + Footer.
|
|
2
2
|
// Each Section stacks vertically; the feature Columns collapse to one per row on
|
|
3
3
|
// mobile (Bulma columns stack below the tablet breakpoint).
|
|
4
|
-
|
|
4
|
+
//
|
|
5
|
+
// The Navbar's burger/menu is CONTROLLED: `active` on Navbar.Menu shows/hides
|
|
6
|
+
// the mobile menu, while `active` + `onClick` on Navbar.Burger make the burger
|
|
7
|
+
// toggle it and animate. Wire the same state to both — left unwired, clicking
|
|
8
|
+
// the burger does nothing; desktop looks fine and nothing errors, so the
|
|
9
|
+
// failure is silent. A fixed-top navbar
|
|
10
|
+
// also needs the `has-navbar-fixed-top` class on <html> so the page is padded
|
|
11
|
+
// below it (never an inline padding offset) — Bulma requires this and the
|
|
12
|
+
// library does NOT add it for you.
|
|
13
|
+
import React, { useEffect, useState } from 'react';
|
|
5
14
|
import {
|
|
15
|
+
Navbar,
|
|
6
16
|
Hero,
|
|
7
17
|
Section,
|
|
8
18
|
Container,
|
|
@@ -24,8 +34,38 @@ const FEATURES = [
|
|
|
24
34
|
];
|
|
25
35
|
|
|
26
36
|
export default function LandingPage() {
|
|
37
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
document.documentElement.classList.add('has-navbar-fixed-top');
|
|
41
|
+
return () => {
|
|
42
|
+
document.documentElement.classList.remove('has-navbar-fixed-top');
|
|
43
|
+
};
|
|
44
|
+
}, []);
|
|
45
|
+
|
|
27
46
|
return (
|
|
28
47
|
<>
|
|
48
|
+
<Navbar fixed="top">
|
|
49
|
+
<Navbar.Brand>
|
|
50
|
+
<Navbar.Item href="#">Acme</Navbar.Item>
|
|
51
|
+
<Navbar.Burger
|
|
52
|
+
active={menuOpen}
|
|
53
|
+
onClick={() => setMenuOpen(open => !open)}
|
|
54
|
+
aria-label="menu"
|
|
55
|
+
aria-expanded={menuOpen}
|
|
56
|
+
/>
|
|
57
|
+
</Navbar.Brand>
|
|
58
|
+
<Navbar.Menu active={menuOpen}>
|
|
59
|
+
<Navbar.Start>
|
|
60
|
+
<Navbar.Item href="#">Features</Navbar.Item>
|
|
61
|
+
<Navbar.Item href="#">Pricing</Navbar.Item>
|
|
62
|
+
</Navbar.Start>
|
|
63
|
+
<Navbar.End>
|
|
64
|
+
<Navbar.Item href="#">Sign in</Navbar.Item>
|
|
65
|
+
</Navbar.End>
|
|
66
|
+
</Navbar.Menu>
|
|
67
|
+
</Navbar>
|
|
68
|
+
|
|
29
69
|
<Hero color="primary" size="medium">
|
|
30
70
|
<Hero.Body>
|
|
31
71
|
<Container textAlign="centered">
|
|
@@ -19,6 +19,8 @@ app".
|
|
|
19
19
|
**Skeleton:**
|
|
20
20
|
|
|
21
21
|
```tsx
|
|
22
|
+
const [open, setOpen] = useState(false); // controls the burger + mobile menu
|
|
23
|
+
|
|
22
24
|
<>
|
|
23
25
|
<Navbar fixed="top" color="dark">
|
|
24
26
|
<Navbar.Brand>
|
|
@@ -54,7 +56,7 @@ app".
|
|
|
54
56
|
</Column>
|
|
55
57
|
</Columns>
|
|
56
58
|
</Container>
|
|
57
|
-
|
|
59
|
+
</>;
|
|
58
60
|
```
|
|
59
61
|
|
|
60
62
|
**Required:** add `has-navbar-fixed-top` to `<html>` (see `examples/app-shell.tsx`) so content is
|
|
@@ -74,7 +76,29 @@ pricing page. The default for "build me a site/page".
|
|
|
74
76
|
**Skeleton:**
|
|
75
77
|
|
|
76
78
|
```tsx
|
|
79
|
+
const [open, setOpen] = useState(false); // controls the burger + mobile menu
|
|
80
|
+
|
|
77
81
|
<>
|
|
82
|
+
<Navbar fixed="top">
|
|
83
|
+
<Navbar.Brand>
|
|
84
|
+
<Navbar.Item href="#">Brand</Navbar.Item>
|
|
85
|
+
<Navbar.Burger
|
|
86
|
+
active={open}
|
|
87
|
+
onClick={() => setOpen(o => !o)}
|
|
88
|
+
aria-label="menu"
|
|
89
|
+
/>
|
|
90
|
+
</Navbar.Brand>
|
|
91
|
+
<Navbar.Menu active={open}>
|
|
92
|
+
<Navbar.Start>
|
|
93
|
+
<Navbar.Item href="#">Features</Navbar.Item>
|
|
94
|
+
<Navbar.Item href="#">Pricing</Navbar.Item>
|
|
95
|
+
</Navbar.Start>
|
|
96
|
+
<Navbar.End>
|
|
97
|
+
<Navbar.Item href="#">Sign in</Navbar.Item>
|
|
98
|
+
</Navbar.End>
|
|
99
|
+
</Navbar.Menu>
|
|
100
|
+
</Navbar>
|
|
101
|
+
|
|
78
102
|
<Hero color="primary" size="medium">
|
|
79
103
|
<Hero.Body>
|
|
80
104
|
<Container textAlign="centered">
|
|
@@ -110,10 +134,18 @@ pricing page. The default for "build me a site/page".
|
|
|
110
134
|
<Content textAlign="centered">{/* footer */}</Content>
|
|
111
135
|
</Container>
|
|
112
136
|
</Footer>
|
|
113
|
-
|
|
137
|
+
</>;
|
|
114
138
|
```
|
|
115
139
|
|
|
116
|
-
**
|
|
140
|
+
**Required:** `Navbar.Burger`/`Navbar.Menu` are **controlled** — wire the same `active` state to
|
|
141
|
+
both: `active` on `Navbar.Menu` shows/hides the mobile menu, and `active` + `onClick` on
|
|
142
|
+
`Navbar.Burger` make the burger toggle it and animate (a bare `<Navbar.Burger />` does nothing
|
|
143
|
+
when clicked, with no error). And add
|
|
144
|
+
`has-navbar-fixed-top` to `<html>` (see `examples/landing.tsx`) so content is not hidden behind
|
|
145
|
+
the fixed navbar — never an inline padding offset.
|
|
146
|
+
|
|
147
|
+
**Responsive:** the navbar collapses to a burger on mobile (`Navbar.Burger` + `Navbar.Menu active`).
|
|
148
|
+
`Section`s already stack vertically. The feature `Columns` collapse to one feature
|
|
117
149
|
per row on mobile. Use `Hero size="large"` / `"fullheight"` for a taller hero.
|
|
118
150
|
|
|
119
151
|
**Hero CTAs:** on a colored hero use **filled** buttons only — `color="light"` for the primary
|