@semplice-studio/pa-design-system 0.1.1 → 0.3.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 +85 -128
- package/dist/components/PaAccordion/PaAccordion.vue.d.ts +0 -1
- package/dist/components/PaAccordion/PaAccordion.vue.js +3 -5
- package/dist/components/PaAccordion/PaAccordion.vue.js.map +1 -1
- package/dist/components/PaAccordion/PaAccordion.vue2.js +24 -30
- package/dist/components/PaAccordion/PaAccordion.vue2.js.map +1 -1
- package/dist/components/PaBanner/PaBanner.vue.js +6 -6
- package/dist/components/PaBanner/PaBanner.vue2.js +26 -28
- package/dist/components/PaBanner/PaBanner.vue2.js.map +1 -1
- package/dist/components/PaCard/PaCard.vue.d.ts +17 -14
- package/dist/components/PaCard/PaCard.vue.js +2 -2
- package/dist/components/PaCard/PaCard.vue2.js +37 -42
- package/dist/components/PaCard/PaCard.vue2.js.map +1 -1
- package/dist/components/PaCheckbox/PaCheckbox.vue.d.ts +5 -6
- package/dist/components/PaCheckbox/PaCheckbox.vue.js +2 -4
- package/dist/components/PaCheckbox/PaCheckbox.vue.js.map +1 -1
- package/dist/components/PaCheckbox/PaCheckbox.vue2.js +20 -26
- package/dist/components/PaCheckbox/PaCheckbox.vue2.js.map +1 -1
- package/dist/components/PaCheckboxGroup/PaCheckboxGroup.vue.d.ts +5 -6
- package/dist/components/PaCheckboxGroup/PaCheckboxGroup.vue.js +2 -4
- package/dist/components/PaCheckboxGroup/PaCheckboxGroup.vue.js.map +1 -1
- package/dist/components/PaCheckboxGroup/PaCheckboxGroup.vue2.js +25 -31
- package/dist/components/PaCheckboxGroup/PaCheckboxGroup.vue2.js.map +1 -1
- package/dist/components/PaDatePicker/PaDatePicker.vue.d.ts +13 -26
- package/dist/components/PaDatePicker/PaDatePicker.vue.js +4 -6
- package/dist/components/PaDatePicker/PaDatePicker.vue.js.map +1 -1
- package/dist/components/PaDatePicker/PaDatePicker.vue2.js +53 -59
- package/dist/components/PaDatePicker/PaDatePicker.vue2.js.map +1 -1
- package/dist/components/PaDrawer/PaDrawer.vue.js +2 -2
- package/dist/components/PaDrawer/PaDrawer.vue2.js +37 -41
- package/dist/components/PaDrawer/PaDrawer.vue2.js.map +1 -1
- package/dist/components/PaFileUpload/PaFileUpload.vue.d.ts +0 -1
- package/dist/components/PaFileUpload/PaFileUpload.vue.js +3 -5
- package/dist/components/PaFileUpload/PaFileUpload.vue.js.map +1 -1
- package/dist/components/PaFileUpload/PaFileUpload.vue2.js +22 -28
- package/dist/components/PaFileUpload/PaFileUpload.vue2.js.map +1 -1
- package/dist/components/PaFooter/PaFooter.vue.js +1 -1
- package/dist/components/PaFooter/PaFooter.vue2.js +43 -48
- package/dist/components/PaFooter/PaFooter.vue2.js.map +1 -1
- package/dist/components/PaHeaderDesktop/PaHeaderDesktop.vue.js +1 -1
- package/dist/components/PaHeaderDesktop/PaHeaderDesktop.vue2.js +61 -66
- package/dist/components/PaHeaderDesktop/PaHeaderDesktop.vue2.js.map +1 -1
- package/dist/components/PaHeaderMobile/PaHeaderMobile.vue.js +2 -2
- package/dist/components/PaHeaderMobile/PaHeaderMobile.vue2.js +69 -74
- package/dist/components/PaHeaderMobile/PaHeaderMobile.vue2.js.map +1 -1
- package/dist/components/PaHero/PaHero.vue.d.ts +15 -12
- package/dist/components/PaHero/PaHero.vue.js +2 -2
- package/dist/components/PaHero/PaHero.vue2.js +36 -41
- package/dist/components/PaHero/PaHero.vue2.js.map +1 -1
- package/dist/components/PaInput/PaInput.vue.d.ts +15 -13
- package/dist/components/PaInput/PaInput.vue.js +4 -6
- package/dist/components/PaInput/PaInput.vue.js.map +1 -1
- package/dist/components/PaInput/PaInput.vue2.js +27 -33
- package/dist/components/PaInput/PaInput.vue2.js.map +1 -1
- package/dist/components/PaModal/PaModal.vue.d.ts +14 -11
- package/dist/components/PaModal/PaModal.vue.js +3 -3
- package/dist/components/PaModal/PaModal.vue2.js +41 -46
- package/dist/components/PaModal/PaModal.vue2.js.map +1 -1
- package/dist/components/PaMonthPicker/PaMonthPicker.vue.d.ts +13 -26
- package/dist/components/PaMonthPicker/PaMonthPicker.vue.js +2 -4
- package/dist/components/PaMonthPicker/PaMonthPicker.vue.js.map +1 -1
- package/dist/components/PaMonthPicker/PaMonthPicker.vue2.js +64 -70
- package/dist/components/PaMonthPicker/PaMonthPicker.vue2.js.map +1 -1
- package/dist/components/PaPagination/PaPagination.vue.js +2 -2
- package/dist/components/PaPagination/PaPagination.vue2.js +41 -46
- package/dist/components/PaPagination/PaPagination.vue2.js.map +1 -1
- package/dist/components/PaRadioGroup/PaRadioGroup.vue.d.ts +5 -6
- package/dist/components/PaRadioGroup/PaRadioGroup.vue.js +2 -4
- package/dist/components/PaRadioGroup/PaRadioGroup.vue.js.map +1 -1
- package/dist/components/PaRadioGroup/PaRadioGroup.vue2.js +22 -28
- package/dist/components/PaRadioGroup/PaRadioGroup.vue2.js.map +1 -1
- package/dist/components/PaRangePicker/PaRangePicker.vue.d.ts +0 -1
- package/dist/components/PaRangePicker/PaRangePicker.vue.js +4 -6
- package/dist/components/PaRangePicker/PaRangePicker.vue.js.map +1 -1
- package/dist/components/PaRangePicker/PaRangePicker.vue2.js +76 -82
- package/dist/components/PaRangePicker/PaRangePicker.vue2.js.map +1 -1
- package/dist/components/PaSearchBar/PaSearchBar.vue.d.ts +0 -1
- package/dist/components/PaSearchBar/PaSearchBar.vue.js +3 -5
- package/dist/components/PaSearchBar/PaSearchBar.vue.js.map +1 -1
- package/dist/components/PaSearchBar/PaSearchBar.vue2.js +55 -61
- package/dist/components/PaSearchBar/PaSearchBar.vue2.js.map +1 -1
- package/dist/components/PaSelect/PaSelect.vue.d.ts +5 -6
- package/dist/components/PaSelect/PaSelect.vue.js +4 -6
- package/dist/components/PaSelect/PaSelect.vue.js.map +1 -1
- package/dist/components/PaSelect/PaSelect.vue2.js +25 -31
- package/dist/components/PaSelect/PaSelect.vue2.js.map +1 -1
- package/dist/components/PaTabs/PaTabs.vue.js +1 -1
- package/dist/components/PaTabs/PaTabs.vue2.js +17 -19
- package/dist/components/PaTabs/PaTabs.vue2.js.map +1 -1
- package/dist/components/PaTextarea/PaTextarea.vue.d.ts +5 -6
- package/dist/components/PaTextarea/PaTextarea.vue.js +4 -6
- package/dist/components/PaTextarea/PaTextarea.vue.js.map +1 -1
- package/dist/components/PaTextarea/PaTextarea.vue2.js +16 -22
- package/dist/components/PaTextarea/PaTextarea.vue2.js.map +1 -1
- package/dist/components/PaTimePicker/PaTimePicker.vue.d.ts +0 -1
- package/dist/components/PaTimePicker/PaTimePicker.vue.js +2 -4
- package/dist/components/PaTimePicker/PaTimePicker.vue.js.map +1 -1
- package/dist/components/PaTimePicker/PaTimePicker.vue2.js +44 -50
- package/dist/components/PaTimePicker/PaTimePicker.vue2.js.map +1 -1
- package/dist/components/PaTitleBar/PaTitleBar.vue.d.ts +12 -9
- package/dist/components/PaTitleBar/PaTitleBar.vue.js +2 -2
- package/dist/components/PaTitleBar/PaTitleBar.vue2.js +34 -39
- package/dist/components/PaTitleBar/PaTitleBar.vue2.js.map +1 -1
- package/dist/components/PaToggle/PaToggle.vue.d.ts +0 -1
- package/dist/components/PaToggle/PaToggle.vue.js +2 -4
- package/dist/components/PaToggle/PaToggle.vue.js.map +1 -1
- package/dist/components/PaToggle/PaToggle.vue2.js +20 -26
- package/dist/components/PaToggle/PaToggle.vue2.js.map +1 -1
- package/dist/components/PaYearPicker/PaYearPicker.vue.d.ts +13 -26
- package/dist/components/PaYearPicker/PaYearPicker.vue.js +4 -6
- package/dist/components/PaYearPicker/PaYearPicker.vue.js.map +1 -1
- package/dist/components/PaYearPicker/PaYearPicker.vue2.js +70 -76
- package/dist/components/PaYearPicker/PaYearPicker.vue2.js.map +1 -1
- package/dist/style.css +1 -1
- package/docs/design-system.md +590 -0
- package/docs/layouts.md +297 -0
- package/docs/page-composition-examples.md +286 -0
- package/docs/public-surface.md +68 -0
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -1,166 +1,123 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @semplice-studio/pa-design-system
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Vue 3 design system for Italian **Pubblica Amministrazione (PA)** web portals — accessible, brand-consistent components and design tokens, by [Semplice](https://semplice.is).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- **41 components** (15 atoms + 26 composed) — forms, navigation, overlays, data display, date/time pickers
|
|
6
|
+
- **Design tokens as CSS custom properties**, with Inter + Roboto Mono bundled via `@font-face`
|
|
7
|
+
- **Accessibility-first**: WAI-ARIA patterns, keyboard navigation, focus management — built toward Italian PA requirements (AgID / Legge Stanca)
|
|
8
|
+
- **ESM-only**, tree-shakeable, typed (`.d.ts` for every component)
|
|
9
|
+
- Italian default labels everywhere, overridable via props for other locales
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
> ⚠️ **Pre-1.0**: minor versions may contain breaking changes until `v1.0.0`.
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
- **One conversation per phase.** Each skill is a guided Q&A that produces one durable artifact (PRD, design system, data model, user story).
|
|
11
|
-
- **Plan first, develop second.** No code is written before a plan is confirmed. Stories are drafted before they're built. Components are mapped before they're composed.
|
|
12
|
-
- **Per-step approval.** The agent never batch-implements. Every user story gets its own approval gate.
|
|
13
|
+
## Requirements
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
- Vue **≥ 3.4**
|
|
16
|
+
- Node **≥ 20** (build tooling)
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
## Installation
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
1. Clone this template → empty repo with .claude/ + docs/ scaffolding
|
|
22
|
-
2. /init-prd → dialog → docs/prd.md + populated CLAUDE.md
|
|
23
|
-
3. /import-design-system → Figma → docs/frontend/design-system.md + tokens
|
|
24
|
-
4. /data-model → dialog → docs/data-model.md + schema sketch
|
|
25
|
-
5. /user-story <topic> → Q&A → docs/user-stories/user-stories-vX.X.md
|
|
26
|
-
6. /user-story implement vX.X → loop: plan → approve → implement → tick AC
|
|
27
|
-
7. git commit → one bundled commit per story
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
### Library / npm package project (e.g. a Vue design system)
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
1. Clone this template → empty repo with .claude/ + docs/ scaffolding
|
|
34
|
-
2. /init-library → dialog → docs/prd.md (library spec) + CLAUDE.md
|
|
35
|
-
+ optional package.json + tsconfig + build config
|
|
36
|
-
3. /import-design-system → Figma → docs/frontend/design-system.md + tokens
|
|
37
|
-
4. (skip /data-model — libraries have no data model)
|
|
38
|
-
5. /user-story <component> → Q&A → docs/user-stories/user-stories-vX.X.md
|
|
39
|
-
6. /user-story implement vX.X → loop: plan → approve → /figma-component → tick AC
|
|
40
|
-
7. git commit → one bundled commit per story (or per component)
|
|
20
|
+
```bash
|
|
21
|
+
pnpm add @semplice-studio/pa-design-system
|
|
22
|
+
# or: npm install / yarn add
|
|
41
23
|
```
|
|
42
24
|
|
|
43
|
-
|
|
25
|
+
`@phosphor-icons/vue` and `v-calendar` are installed automatically as dependencies; `vue` is a peer.
|
|
44
26
|
|
|
45
|
-
##
|
|
27
|
+
## Quickstart — Nuxt 3/4
|
|
46
28
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
29
|
+
```ts
|
|
30
|
+
// nuxt.config.ts
|
|
31
|
+
export default defineNuxtConfig({
|
|
32
|
+
css: [
|
|
33
|
+
'@semplice-studio/pa-design-system/tokens.css',
|
|
34
|
+
'@semplice-studio/pa-design-system/style.css',
|
|
35
|
+
],
|
|
36
|
+
})
|
|
37
|
+
```
|
|
53
38
|
|
|
54
|
-
|
|
39
|
+
```vue
|
|
40
|
+
<script setup lang="ts">
|
|
41
|
+
import { PaButton, PaInput } from '@semplice-studio/pa-design-system'
|
|
42
|
+
</script>
|
|
55
43
|
|
|
56
|
-
|
|
44
|
+
<template>
|
|
45
|
+
<PaInput v-model="name" label="Nome" />
|
|
46
|
+
<PaButton @click="submit">Invia</PaButton>
|
|
47
|
+
</template>
|
|
48
|
+
```
|
|
57
49
|
|
|
58
|
-
|
|
59
|
-
|---|---|---|---|
|
|
60
|
-
| Requirements / discovery | `/init-prd` (product) or `/init-library` (npm package) | `docs/prd.md` + populated `CLAUDE.md` | Personas/package surface, scope, stack, constraints |
|
|
61
|
-
| UX / visual design | `/import-design-system` | `docs/frontend/design-system.md` + token files + Figma→component recognition rules | Components available, token names, icon registry |
|
|
62
|
-
| System / data design | `/data-model` | `docs/data-model.md` + ORM schema sketch | Entities, relationships, indexes, RLS policies *(skip for library projects)* |
|
|
50
|
+
## Quickstart — plain Vue + Vite
|
|
63
51
|
|
|
64
|
-
|
|
52
|
+
```ts
|
|
53
|
+
// main.ts
|
|
54
|
+
import '@semplice-studio/pa-design-system/tokens.css'
|
|
55
|
+
import '@semplice-studio/pa-design-system/style.css'
|
|
56
|
+
```
|
|
65
57
|
|
|
66
|
-
|
|
58
|
+
Then import components where you use them — no plugin, no global registration.
|
|
67
59
|
|
|
68
|
-
|
|
69
|
-
|---|---|---|---|
|
|
70
|
-
| Sprint planning | `/user-story <topic>` | `docs/user-stories/user-stories-vX.X.md` | One file per release. Stories scoped, AC testable, files listed. |
|
|
71
|
-
| Implementation | `/user-story implement vX.X` | Source code + ticked AC | Per-step approval. Calls `/ui-composer` and `/figma-component` as sub-skills when needed. |
|
|
72
|
-
| Component design (sub-skill) | `/figma-component <Name> <figma-url>` | Component file + design-system.md update (status 🟡 → ✅) | Only when a story needs a new atom. |
|
|
73
|
-
| Page composition (sub-skill) | `/ui-composer` | Page file with mock data, AC checklist | Only when a story scaffolds a page from existing atoms. |
|
|
74
|
-
| Review / merge | (manual) | git commit per story | One bundled commit per story; commit message follows `feat(area): <summary> (US-NN)`. |
|
|
60
|
+
## Imports
|
|
75
61
|
|
|
76
|
-
|
|
62
|
+
```ts
|
|
63
|
+
// barrel — tree-shaken by your bundler
|
|
64
|
+
import { PaButton, PaModal } from '@semplice-studio/pa-design-system'
|
|
77
65
|
|
|
78
|
-
|
|
66
|
+
// or per-component subpath
|
|
67
|
+
import { PaButton } from '@semplice-studio/pa-design-system/components/PaButton'
|
|
68
|
+
```
|
|
79
69
|
|
|
80
|
-
|
|
70
|
+
Every component also exports its prop/option types (`PaButtonProps`, `PaSelectOption`, …).
|
|
81
71
|
|
|
82
|
-
|
|
83
|
-
- `/user-story implement` ticks acceptance criteria (✅) in the story file and proposes commits
|
|
84
|
-
- New conventions discovered during implementation get appended to the relevant `docs/tech/*.md`
|
|
85
|
-
- `/data-model` is re-runnable when entities change — diffs against the existing model
|
|
72
|
+
## Stylesheets
|
|
86
73
|
|
|
87
|
-
|
|
74
|
+
| Entry | Contents |
|
|
75
|
+
|---|---|
|
|
76
|
+
| `tokens.css` | Design tokens (`--pa-color-*`, `--pa-space-*`, `--pa-font-*`, …) + bundled Inter / Roboto Mono `@font-face` — no separate font loading needed. Auto-imports `layout.css`. |
|
|
77
|
+
| `layout.css` | `.pa-*` layout/composition utilities (also importable standalone) |
|
|
78
|
+
| `style.css` | Compiled component styles |
|
|
88
79
|
|
|
89
|
-
|
|
80
|
+
## Theming
|
|
90
81
|
|
|
91
|
-
|
|
82
|
+
All component styling resolves through CSS custom properties — override them at the consumer level, no build-time config:
|
|
92
83
|
|
|
93
|
-
|
|
84
|
+
```css
|
|
85
|
+
:root {
|
|
86
|
+
--pa-color-primary: #0a5fad;
|
|
87
|
+
}
|
|
94
88
|
```
|
|
95
|
-
git clone <template> dx-design-system && cd dx-design-system && claude
|
|
96
|
-
> /init-library
|
|
97
|
-
```
|
|
98
|
-
The agent Q&As through 18 questions (package name, target framework, build tool, peer deps, distribution shape). ~30 min later: `docs/prd.md` is filled with the library spec, `CLAUDE.md` is populated, optional `package.json` + `tsconfig.json` + build config are scaffolded. *Phase: Requirements engineering.*
|
|
99
89
|
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
> /import-design-system
|
|
103
|
-
```
|
|
104
|
-
The agent extracts color/typography/spacing/radius tokens from Figma, enumerates atoms and composed components, builds the icon registry. Output: `docs/frontend/design-system.md` (every component marked 🟡 designed, awaiting implementation), `src/tokens/*.css`, Figma→component recognition rules seeded. *Phase: UX/visual design.*
|
|
90
|
+
## Component reference & agent docs
|
|
105
91
|
|
|
106
|
-
**(
|
|
92
|
+
These docs ship **inside the package** (`node_modules/@semplice-studio/pa-design-system/docs/`), version-locked to the installed release — point your coding agent at them:
|
|
107
93
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
The agent Q&As scope, AC, file paths, dependencies. Output: `docs/user-stories/user-stories-v1.1.md` with ~6 user stories (US-01 → US-06), each with concrete AC and file paths. *Phase: Sprint planning.*
|
|
94
|
+
- [`docs/public-surface.md`](docs/public-surface.md) — export table: every component with its props/v-model/slots/emits summary
|
|
95
|
+
- [`docs/page-composition-examples.md`](docs/page-composition-examples.md) — page skeleton + section patterns distilled from the reference templates
|
|
96
|
+
- [`docs/layouts.md`](docs/layouts.md) — the `.pa-*` layout utility classes
|
|
97
|
+
- [`docs/design-system.md`](docs/design-system.md) — design tokens + component registry
|
|
113
98
|
|
|
114
|
-
|
|
115
|
-
```
|
|
116
|
-
> /user-story implement v1.1
|
|
117
|
-
```
|
|
118
|
-
For each US-NN: agent proposes a plan → user approves → agent calls `/figma-component UiButton <figma-url>` as a sub-skill → component generated → `docs/frontend/design-system.md` updated (status 🟡 → ✅) → AC ticked → commit suggested (`feat(button): add UiButton with primary/outline/ghost variants (US-01)`). Loop continues for each story. *Phase: Implementation, with continuous documentation woven in.*
|
|
99
|
+
For live examples, run the Histoire playground (see Development).
|
|
119
100
|
|
|
120
|
-
|
|
121
|
-
```
|
|
122
|
-
> /user-story Composed components: Card, Header, Sidebar
|
|
123
|
-
```
|
|
124
|
-
The agent reads `CLAUDE.md`, `docs/prd.md`, `docs/frontend/design-system.md` (now with 5 ✅ atoms it can compose with), and the previous user-stories file as structural reference. Phase B repeats — but the knowledge base is bigger and the agent's plans are sharper. *Phase: next iteration of sprint planning + implementation.*
|
|
101
|
+
Conventions that apply across the library:
|
|
125
102
|
|
|
126
|
-
|
|
103
|
+
- **Shared form anatomy**: form components mirror `PaInput`'s `label` / `helperText` / `error` / `valid` / `required` / `disabled` / `readonly` set
|
|
104
|
+
- **Date/time pickers**: values normalized to *local* midnight (never UTC); with `name` set, a hidden input serializes for native form posts
|
|
105
|
+
- **Responsive components use container queries** — they reflow inside narrow sidebars regardless of viewport
|
|
106
|
+
- **SPA routing**: nav components (`PaBreadcrumb`, headers, footer) emit preventable payloads — call `preventDefault()` and route with your router
|
|
127
107
|
|
|
128
|
-
##
|
|
108
|
+
## Development
|
|
129
109
|
|
|
110
|
+
```bash
|
|
111
|
+
pnpm install
|
|
112
|
+
pnpm dev # Histoire playground
|
|
113
|
+
pnpm test # Vitest (watch)
|
|
114
|
+
pnpm build # library build + type emit
|
|
115
|
+
pnpm typecheck
|
|
116
|
+
pnpm lint
|
|
130
117
|
```
|
|
131
|
-
template/
|
|
132
|
-
├── AUDIT.md ← what's reusable methodology vs Sapra-specific
|
|
133
|
-
├── CLAUDE.md ← skeleton with {{TODO}} slots filled by skills
|
|
134
|
-
├── .claude/skills/
|
|
135
|
-
│ ├── init-prd/ ← NEW: bootstrap a product/app project
|
|
136
|
-
│ ├── init-library/ ← NEW: bootstrap a library/npm package project
|
|
137
|
-
│ ├── import-design-system/ ← NEW: Figma → design-system.md + tokens
|
|
138
|
-
│ ├── data-model/ ← NEW: entities + relationships → data-model.md
|
|
139
|
-
│ ├── user-story/ ← LIFTED from Sapra (deparametrized)
|
|
140
|
-
│ ├── ui-composer/ ← LIFTED from Sapra (deparametrized)
|
|
141
|
-
│ └── figma-component/ ← LIFTED from Sapra (deparametrized, now a skill)
|
|
142
|
-
└── docs/
|
|
143
|
-
├── workflow.md ← Plan-first/Develop-second workflow rules
|
|
144
|
-
├── prd.md ← empty template, filled by /init-prd
|
|
145
|
-
├── data-model.md ← empty template, filled by /data-model
|
|
146
|
-
├── frontend/
|
|
147
|
-
│ └── design-system.md ← empty template, filled by /import-design-system
|
|
148
|
-
└── user-stories/ ← created per release by /user-story
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
## How to use
|
|
152
|
-
|
|
153
|
-
1. Copy `template/` contents to a fresh repo (the `template/` folder itself is for reference inside Sapra)
|
|
154
|
-
2. Open it in Claude Code — the agent reads `CLAUDE.md` on session start
|
|
155
|
-
3. Decide: is this a **product** or a **library**?
|
|
156
|
-
- Product/app → run `/init-prd`. Q&A through tech stack, product surface, constraints
|
|
157
|
-
- Library (npm package, design system, SDK) → run `/init-library`. Q&A through package surface, peer deps, build, distribution
|
|
158
|
-
4. Run `/import-design-system` once your designer has a Figma file ready
|
|
159
|
-
5. Run `/data-model` to lock down entities before any backend work — **skip for library projects**
|
|
160
|
-
6. From there: `/user-story` per feature/component, then `implement vX.X` per release
|
|
161
118
|
|
|
162
|
-
|
|
119
|
+
Releases use [changesets](https://github.com/changesets/changesets): `pnpm changeset` → `pnpm changeset version` → commit → `pnpm release` → `git push --follow-tags`. Published publicly on npmjs.com (`publishConfig.access: public`); publishing requires npm 2FA.
|
|
163
120
|
|
|
164
|
-
|
|
121
|
+
## License
|
|
165
122
|
|
|
166
|
-
|
|
123
|
+
[EUPL-1.2](LICENSE) © Semplice
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import o from "./PaAccordion.vue2.js";
|
|
2
|
-
import { nextPaAccordionId as p } from "./PaAccordion.vue2.js";
|
|
3
2
|
/* empty css */
|
|
4
|
-
import
|
|
5
|
-
const
|
|
3
|
+
import a from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
+
const f = /* @__PURE__ */ a(o, [["__scopeId", "data-v-83f7afca"]]);
|
|
6
5
|
export {
|
|
7
|
-
|
|
8
|
-
p as nextPaAccordionId
|
|
6
|
+
f as default
|
|
9
7
|
};
|
|
10
8
|
//# sourceMappingURL=PaAccordion.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PaAccordion.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PaAccordion.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import { defineComponent as B, getCurrentInstance as
|
|
1
|
+
import { defineComponent as B, getCurrentInstance as C, useId as I, computed as c, inject as $, ref as k, onMounted as x, onBeforeUnmount as w, openBlock as v, createElementBlock as N, createElementVNode as r, createBlock as O, createCommentVNode as P, renderSlot as f, createTextVNode as S, toDisplayString as z, createVNode as _, Transition as A, withCtx as D, withDirectives as E, vShow as T } from "vue";
|
|
2
2
|
import g from "../PaIcon/PaIcon.vue.js";
|
|
3
|
-
import { PaAccordionGroupKey as
|
|
4
|
-
const
|
|
5
|
-
let U = 0;
|
|
6
|
-
function q() {
|
|
7
|
-
return `pa-accordion-${++U}`;
|
|
8
|
-
}
|
|
9
|
-
const R = /* @__PURE__ */ B({
|
|
3
|
+
import { PaAccordionGroupKey as j } from "./groupKey.js";
|
|
4
|
+
const G = ["data-open"], K = ["id", "aria-expanded", "aria-controls"], M = { class: "pa-accordion__title" }, U = ["id", "aria-labelledby"], Q = /* @__PURE__ */ B({
|
|
10
5
|
__name: "PaAccordion",
|
|
11
6
|
props: {
|
|
12
7
|
modelValue: { type: Boolean },
|
|
@@ -17,16 +12,16 @@ const R = /* @__PURE__ */ B({
|
|
|
17
12
|
},
|
|
18
13
|
emits: ["update:modelValue"],
|
|
19
14
|
setup(t, { emit: h }) {
|
|
20
|
-
const l = t, y = h, d =
|
|
15
|
+
const l = t, y = h, d = C().vnode.props ?? {}, s = "modelValue" in d || "model-value" in d, V = `pa-accordion-${I()}`, o = c(() => l.id ?? V), u = c(() => `${o.value}-header`), p = c(() => `${o.value}-panel`), e = $(j, null), a = e ? e.isOpen(o.value) : null, m = k(l.defaultOpen), i = c(() => a ? a.value : s ? !!l.modelValue : m.value);
|
|
21
16
|
function b() {
|
|
22
|
-
const
|
|
23
|
-
e ? e.toggle(o.value) : s || (m.value =
|
|
17
|
+
const n = !i.value;
|
|
18
|
+
e ? e.toggle(o.value) : s || (m.value = n), y("update:modelValue", n);
|
|
24
19
|
}
|
|
25
|
-
return
|
|
26
|
-
e && (e.register(o.value), l.defaultOpen && !(
|
|
27
|
-
}),
|
|
20
|
+
return x(() => {
|
|
21
|
+
e && (e.register(o.value), l.defaultOpen && !(a != null && a.value) && e.toggle(o.value));
|
|
22
|
+
}), w(() => {
|
|
28
23
|
e && e.unregister(o.value);
|
|
29
|
-
}), (
|
|
24
|
+
}), (n, F) => (v(), N("div", {
|
|
30
25
|
class: "pa-accordion",
|
|
31
26
|
"data-open": i.value
|
|
32
27
|
}, [
|
|
@@ -38,15 +33,15 @@ const R = /* @__PURE__ */ B({
|
|
|
38
33
|
"aria-controls": p.value,
|
|
39
34
|
onClick: b
|
|
40
35
|
}, [
|
|
41
|
-
t.icon ? (v(),
|
|
36
|
+
t.icon ? (v(), O(g, {
|
|
42
37
|
key: 0,
|
|
43
38
|
name: t.icon,
|
|
44
39
|
size: "sm",
|
|
45
40
|
class: "pa-accordion__icon"
|
|
46
|
-
}, null, 8, ["name"])) :
|
|
47
|
-
r("span",
|
|
48
|
-
f(
|
|
49
|
-
|
|
41
|
+
}, null, 8, ["name"])) : P("", !0),
|
|
42
|
+
r("span", M, [
|
|
43
|
+
f(n.$slots, "title", {}, () => [
|
|
44
|
+
S(z(t.title), 1)
|
|
50
45
|
], !0)
|
|
51
46
|
]),
|
|
52
47
|
_(g, {
|
|
@@ -54,27 +49,26 @@ const R = /* @__PURE__ */ B({
|
|
|
54
49
|
size: "sm",
|
|
55
50
|
class: "pa-accordion__chevron"
|
|
56
51
|
})
|
|
57
|
-
], 8,
|
|
58
|
-
_(
|
|
59
|
-
default:
|
|
60
|
-
|
|
52
|
+
], 8, K),
|
|
53
|
+
_(A, { name: "pa-accordion-body" }, {
|
|
54
|
+
default: D(() => [
|
|
55
|
+
E(r("div", {
|
|
61
56
|
class: "pa-accordion__body",
|
|
62
57
|
id: p.value,
|
|
63
58
|
role: "region",
|
|
64
59
|
"aria-labelledby": u.value
|
|
65
60
|
}, [
|
|
66
|
-
f(
|
|
67
|
-
], 8,
|
|
68
|
-
[
|
|
61
|
+
f(n.$slots, "default", {}, void 0, !0)
|
|
62
|
+
], 8, U), [
|
|
63
|
+
[T, i.value]
|
|
69
64
|
])
|
|
70
65
|
]),
|
|
71
66
|
_: 3
|
|
72
67
|
})
|
|
73
|
-
], 8,
|
|
68
|
+
], 8, G));
|
|
74
69
|
}
|
|
75
70
|
});
|
|
76
71
|
export {
|
|
77
|
-
|
|
78
|
-
q as nextPaAccordionId
|
|
72
|
+
Q as default
|
|
79
73
|
};
|
|
80
74
|
//# sourceMappingURL=PaAccordion.vue2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PaAccordion.vue2.js","sources":["../../../src/components/PaAccordion/PaAccordion.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PaIconName } from '../PaIcon'\n\
|
|
1
|
+
{"version":3,"file":"PaAccordion.vue2.js","sources":["../../../src/components/PaAccordion/PaAccordion.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PaIconName } from '../PaIcon'\n\nexport interface PaAccordionProps {\n modelValue?: boolean\n title?: string\n icon?: PaIconName\n defaultOpen?: boolean\n id?: string\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { useId } from 'vue'\nimport {\n computed,\n getCurrentInstance,\n inject,\n onBeforeUnmount,\n onMounted,\n ref,\n} from 'vue'\nimport PaIcon from '../PaIcon/PaIcon.vue'\nimport { PaAccordionGroupKey } from './groupKey'\n\nconst props = withDefaults(defineProps<PaAccordionProps>(), {\n defaultOpen: false,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: boolean): void\n}>()\n\nconst instance = getCurrentInstance()!\nconst initialVnodeProps = instance.vnode.props ?? {}\nconst isControlled =\n 'modelValue' in initialVnodeProps || 'model-value' in initialVnodeProps\n\nconst generatedId = `pa-accordion-${useId()}`\nconst resolvedId = computed(() => props.id ?? generatedId)\nconst headerId = computed(() => `${resolvedId.value}-header`)\nconst panelId = computed(() => `${resolvedId.value}-panel`)\n\nconst group = inject(PaAccordionGroupKey, null)\nconst groupOpen = group ? group.isOpen(resolvedId.value) : null\n\nconst internalOpen = ref(props.defaultOpen)\nconst open = computed(() => {\n if (groupOpen) return groupOpen.value\n if (isControlled) return Boolean(props.modelValue)\n return internalOpen.value\n})\n\nfunction toggle() {\n const next = !open.value\n if (group) {\n group.toggle(resolvedId.value)\n } else if (!isControlled) {\n internalOpen.value = next\n }\n emit('update:modelValue', next)\n}\n\nonMounted(() => {\n if (!group) return\n group.register(resolvedId.value)\n if (props.defaultOpen && !groupOpen?.value) {\n group.toggle(resolvedId.value)\n }\n})\n\nonBeforeUnmount(() => {\n if (group) group.unregister(resolvedId.value)\n})\n</script>\n\n<template>\n <div class=\"pa-accordion\" :data-open=\"open\">\n <button\n class=\"pa-accordion__header\"\n type=\"button\"\n :id=\"headerId\"\n :aria-expanded=\"open\"\n :aria-controls=\"panelId\"\n @click=\"toggle\"\n >\n <PaIcon\n v-if=\"icon\"\n :name=\"icon\"\n size=\"sm\"\n class=\"pa-accordion__icon\"\n />\n <span class=\"pa-accordion__title\">\n <slot name=\"title\">{{ title }}</slot>\n </span>\n <PaIcon\n name=\"caret-down\"\n size=\"sm\"\n class=\"pa-accordion__chevron\"\n />\n </button>\n <Transition name=\"pa-accordion-body\">\n <div\n v-show=\"open\"\n class=\"pa-accordion__body\"\n :id=\"panelId\"\n role=\"region\"\n :aria-labelledby=\"headerId\"\n >\n <slot />\n </div>\n </Transition>\n </div>\n</template>\n\n<style scoped>\n.pa-accordion {\n display: block;\n width: 100%;\n font-family: var(--pa-font-family-base);\n}\n\n.pa-accordion__header {\n display: flex;\n align-items: center;\n gap: var(--pa-space-xs);\n width: 100%;\n padding: var(--pa-space-sm) var(--pa-space-md);\n margin: 0;\n border: none;\n border-radius: var(--pa-radius-smooth);\n background: var(--pa-color-primary);\n color: var(--pa-color-text-white);\n font-family: inherit;\n font-size: var(--pa-font-label-sm-size);\n line-height: var(--pa-font-label-sm-line-height);\n font-weight: var(--pa-font-label-sm-weight);\n text-align: left;\n cursor: pointer;\n}\n\n.pa-accordion__header:focus { outline: none; }\n\n.pa-accordion__header:focus-visible {\n outline: var(--pa-border-sm) solid var(--pa-color-primary-focus-border);\n outline-offset: 2px;\n}\n\n.pa-accordion:not([data-open=\"true\"]) .pa-accordion__header:hover {\n background: var(--pa-color-primary-hover);\n}\n\n.pa-accordion[data-open=\"true\"] .pa-accordion__header {\n background: var(--pa-color-primary-pressed);\n}\n\n.pa-accordion__title {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.pa-accordion__icon {\n flex-shrink: 0;\n}\n\n.pa-accordion__chevron {\n flex-shrink: 0;\n margin-left: auto;\n transition: transform 150ms ease;\n}\n\n.pa-accordion[data-open=\"true\"] .pa-accordion__chevron {\n transform: rotate(180deg);\n}\n\n.pa-accordion[data-open=\"true\"] .pa-accordion__header:hover {\n background: var(--pa-color-primary-hover);\n}\n\n.pa-accordion__body {\n padding: var(--pa-space-md);\n background: var(--pa-color-bg-white);\n color: var(--pa-color-text-black);\n font-family: inherit;\n font-size: var(--pa-font-body-size);\n line-height: var(--pa-font-body-line-height);\n font-weight: var(--pa-font-body-weight);\n}\n\n.pa-accordion-body-enter-active,\n.pa-accordion-body-leave-active {\n transition: opacity 150ms ease, transform 150ms ease;\n}\n\n.pa-accordion-body-enter-from,\n.pa-accordion-body-leave-to {\n opacity: 0;\n transform: translateY(-4px);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .pa-accordion__chevron,\n .pa-accordion-body-enter-active,\n .pa-accordion-body-leave-active {\n transition-duration: 0ms;\n }\n}\n</style>\n"],"names":["props","__props","emit","__emit","initialVnodeProps","getCurrentInstance","isControlled","generatedId","useId","resolvedId","computed","headerId","panelId","group","inject","PaAccordionGroupKey","groupOpen","internalOpen","ref","open","toggle","next","onMounted","onBeforeUnmount","_createElementBlock","_createElementVNode","_createBlock","PaIcon","_hoisted_3","_renderSlot","_ctx","_createVNode","_Transition"],"mappings":";;;;;;;;;;;;;;AAyBA,UAAMA,IAAQC,GAIRC,IAAOC,GAKPC,IADWC,EAAA,EACkB,MAAM,SAAS,CAAA,GAC5CC,IACJ,gBAAgBF,KAAqB,iBAAiBA,GAElDG,IAAc,gBAAgBC,EAAA,CAAO,IACrCC,IAAaC,EAAS,MAAMV,EAAM,MAAMO,CAAW,GACnDI,IAAWD,EAAS,MAAM,GAAGD,EAAW,KAAK,SAAS,GACtDG,IAAUF,EAAS,MAAM,GAAGD,EAAW,KAAK,QAAQ,GAEpDI,IAAQC,EAAOC,GAAqB,IAAI,GACxCC,IAAYH,IAAQA,EAAM,OAAOJ,EAAW,KAAK,IAAI,MAErDQ,IAAeC,EAAIlB,EAAM,WAAW,GACpCmB,IAAOT,EAAS,MAChBM,IAAkBA,EAAU,QAC5BV,IAAqB,EAAQN,EAAM,aAChCiB,EAAa,KACrB;AAED,aAASG,IAAS;AAChB,YAAMC,IAAO,CAACF,EAAK;AACnB,MAAIN,IACFA,EAAM,OAAOJ,EAAW,KAAK,IACnBH,MACVW,EAAa,QAAQI,IAEvBnB,EAAK,qBAAqBmB,CAAI;AAAA,IAChC;AAEA,WAAAC,EAAU,MAAM;AACd,MAAKT,MACLA,EAAM,SAASJ,EAAW,KAAK,GAC3BT,EAAM,eAAe,EAACgB,KAAA,QAAAA,EAAW,UACnCH,EAAM,OAAOJ,EAAW,KAAK;AAAA,IAEjC,CAAC,GAEDc,EAAgB,MAAM;AACpB,MAAIV,KAAOA,EAAM,WAAWJ,EAAW,KAAK;AAAA,IAC9C,CAAC,mBAICe,EAmCM,OAAA;AAAA,MAnCD,OAAM;AAAA,MAAgB,aAAWL,EAAA;AAAA,IAAA;MACpCM,EAsBS,UAAA;AAAA,QArBP,OAAM;AAAA,QACN,MAAK;AAAA,QACJ,IAAId,EAAA;AAAA,QACJ,iBAAeQ,EAAA;AAAA,QACf,iBAAeP,EAAA;AAAA,QACf,SAAOQ;AAAA,MAAA;QAGAnB,EAAA,aADRyB,EAKEC,GAAA;AAAA;UAHC,MAAM1B,EAAA;AAAA,UACP,MAAK;AAAA,UACL,OAAM;AAAA,QAAA;QAERwB,EAEO,QAFPG,GAEO;AAAA,UADLC,EAAqCC,uBAArC,MAAqC;AAAA,gBAAf7B,EAAA,KAAK,GAAA,CAAA;AAAA,UAAA;;QAE7B8B,EAIEJ,GAAA;AAAA,UAHA,MAAK;AAAA,UACL,MAAK;AAAA,UACL,OAAM;AAAA,QAAA;;MAGVI,EAUaC,GAAA,EAVD,MAAK,uBAAmB;AAAA,mBAClC,MAQM;AAAA,YARNP,EAQM,OAAA;AAAA,YANJ,OAAM;AAAA,YACL,IAAIb,EAAA;AAAA,YACL,MAAK;AAAA,YACJ,mBAAiBD,EAAA;AAAA,UAAA;YAElBkB,EAAQC,EAAA,QAAA,WAAA,CAAA,GAAA,QAAA,EAAA;AAAA,UAAA;gBANAX,EAAA,KAAI;AAAA,UAAA;;;;;;;"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import o from "./PaBanner.vue2.js";
|
|
2
|
-
import { VARIANT_A11Y as
|
|
2
|
+
import { VARIANT_A11Y as e, VARIANT_ICONS as f, VARIANT_LABELS as s } from "./PaBanner.vue2.js";
|
|
3
3
|
/* empty css */
|
|
4
4
|
import r from "../../_virtual/_plugin-vue_export-helper.js";
|
|
5
|
-
const
|
|
5
|
+
const a = /* @__PURE__ */ r(o, [["__scopeId", "data-v-17237900"]]);
|
|
6
6
|
export {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
e as VARIANT_A11Y,
|
|
8
|
+
f as VARIANT_ICONS,
|
|
9
|
+
s as VARIANT_LABELS,
|
|
10
|
+
a as default
|
|
11
11
|
};
|
|
12
12
|
//# sourceMappingURL=PaBanner.vue.js.map
|
|
@@ -1,29 +1,27 @@
|
|
|
1
|
-
import { defineComponent as p, computed as o, openBlock as l, createElementBlock as c, normalizeClass as
|
|
1
|
+
import { defineComponent as p, useId as b, computed as o, openBlock as l, createElementBlock as c, normalizeClass as f, createElementVNode as e, createVNode as d, toDisplayString as m, renderSlot as _, createCommentVNode as A } from "vue";
|
|
2
2
|
import v from "../PaIcon/PaIcon.vue.js";
|
|
3
|
-
const
|
|
3
|
+
const h = ["role", "aria-live", "aria-label"], g = { class: "pa-banner__container" }, L = { class: "pa-banner__icon pa-banner__icon--leading" }, N = { class: "pa-banner__content" }, k = { class: "pa-banner__title-row" }, I = { class: "pa-banner__icon pa-banner__icon--inline" }, w = { class: "pa-banner__body" }, V = {
|
|
4
4
|
key: 0,
|
|
5
5
|
class: "pa-banner__action"
|
|
6
|
-
},
|
|
6
|
+
}, $ = {
|
|
7
7
|
info: "info",
|
|
8
8
|
"info-dark": "info",
|
|
9
9
|
success: "check-circle",
|
|
10
10
|
warning: "warning-circle",
|
|
11
11
|
error: "warning"
|
|
12
|
-
},
|
|
12
|
+
}, y = {
|
|
13
13
|
info: { role: "status", ariaLive: "polite" },
|
|
14
14
|
"info-dark": { role: "status", ariaLive: "polite" },
|
|
15
15
|
success: { role: "status", ariaLive: "polite" },
|
|
16
16
|
warning: { role: "alert", ariaLive: "assertive" },
|
|
17
17
|
error: { role: "alert", ariaLive: "assertive" }
|
|
18
|
-
},
|
|
18
|
+
}, z = {
|
|
19
19
|
info: "Avviso",
|
|
20
20
|
"info-dark": "Avviso scuro",
|
|
21
21
|
success: "Notifica di successo",
|
|
22
22
|
warning: "Attenzione",
|
|
23
23
|
error: "Errore"
|
|
24
|
-
}
|
|
25
|
-
let S = 0;
|
|
26
|
-
const E = /* @__PURE__ */ p({
|
|
24
|
+
}, S = /* @__PURE__ */ p({
|
|
27
25
|
__name: "PaBanner",
|
|
28
26
|
props: {
|
|
29
27
|
variant: { default: "info" },
|
|
@@ -31,25 +29,25 @@ const E = /* @__PURE__ */ p({
|
|
|
31
29
|
label: { default: void 0 }
|
|
32
30
|
},
|
|
33
31
|
setup(n) {
|
|
34
|
-
const a = n, r = `pa-banner-${
|
|
35
|
-
return (i,
|
|
36
|
-
class:
|
|
32
|
+
const a = n, r = `pa-banner-${b()}__title`, u = o(() => a.label ?? z[a.variant]), t = o(() => y[a.variant]), s = o(() => $[a.variant]);
|
|
33
|
+
return (i, B) => (l(), c("aside", {
|
|
34
|
+
class: f(["pa-banner", `pa-banner--${n.variant}`]),
|
|
37
35
|
role: t.value.role,
|
|
38
36
|
"aria-live": t.value.ariaLive,
|
|
39
37
|
"aria-labelledby": r,
|
|
40
38
|
"aria-label": u.value
|
|
41
39
|
}, [
|
|
42
|
-
e("div",
|
|
43
|
-
e("div",
|
|
44
|
-
|
|
40
|
+
e("div", g, [
|
|
41
|
+
e("div", L, [
|
|
42
|
+
d(v, {
|
|
45
43
|
name: s.value,
|
|
46
44
|
size: "lg"
|
|
47
45
|
}, null, 8, ["name"])
|
|
48
46
|
]),
|
|
49
|
-
e("div",
|
|
50
|
-
e("div",
|
|
51
|
-
e("div",
|
|
52
|
-
|
|
47
|
+
e("div", N, [
|
|
48
|
+
e("div", k, [
|
|
49
|
+
e("div", I, [
|
|
50
|
+
d(v, {
|
|
53
51
|
name: s.value,
|
|
54
52
|
size: "lg"
|
|
55
53
|
}, null, 8, ["name"])
|
|
@@ -57,23 +55,23 @@ const E = /* @__PURE__ */ p({
|
|
|
57
55
|
e("h3", {
|
|
58
56
|
id: r,
|
|
59
57
|
class: "pa-banner__title"
|
|
60
|
-
},
|
|
58
|
+
}, m(n.title), 1)
|
|
61
59
|
]),
|
|
62
60
|
e("div", w, [
|
|
63
|
-
|
|
61
|
+
_(i.$slots, "default", {}, void 0, !0)
|
|
64
62
|
])
|
|
65
63
|
]),
|
|
66
|
-
i.$slots.action ? (l(), c("div",
|
|
67
|
-
|
|
68
|
-
])) :
|
|
64
|
+
i.$slots.action ? (l(), c("div", V, [
|
|
65
|
+
_(i.$slots, "action", {}, void 0, !0)
|
|
66
|
+
])) : A("", !0)
|
|
69
67
|
])
|
|
70
|
-
], 10,
|
|
68
|
+
], 10, h));
|
|
71
69
|
}
|
|
72
70
|
});
|
|
73
71
|
export {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
y as VARIANT_A11Y,
|
|
73
|
+
$ as VARIANT_ICONS,
|
|
74
|
+
z as VARIANT_LABELS,
|
|
75
|
+
S as default
|
|
78
76
|
};
|
|
79
77
|
//# sourceMappingURL=PaBanner.vue2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PaBanner.vue2.js","sources":["../../../src/components/PaBanner/PaBanner.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PaIconName } from '../PaIcon/PaIcon.vue'\n\nexport type PaBannerVariant =\n | 'info'\n | 'info-dark'\n | 'success'\n | 'warning'\n | 'error'\n\nexport interface PaBannerProps {\n variant?: PaBannerVariant\n title: string\n label?: string\n}\n\nexport const VARIANT_ICONS: Record<PaBannerVariant, PaIconName> = {\n 'info': 'info',\n 'info-dark': 'info',\n 'success': 'check-circle',\n 'warning': 'warning-circle',\n 'error': 'warning',\n}\n\nexport const VARIANT_A11Y: Record<\n PaBannerVariant,\n { role: 'status' | 'alert'; ariaLive: 'polite' | 'assertive' }\n> = {\n 'info': { role: 'status', ariaLive: 'polite' },\n 'info-dark': { role: 'status', ariaLive: 'polite' },\n 'success': { role: 'status', ariaLive: 'polite' },\n 'warning': { role: 'alert', ariaLive: 'assertive' },\n 'error': { role: 'alert', ariaLive: 'assertive' },\n}\n\nexport const VARIANT_LABELS: Record<PaBannerVariant, string> = {\n 'info': 'Avviso',\n 'info-dark': 'Avviso scuro',\n 'success': 'Notifica di successo',\n 'warning': 'Attenzione',\n 'error': 'Errore',\n}\n
|
|
1
|
+
{"version":3,"file":"PaBanner.vue2.js","sources":["../../../src/components/PaBanner/PaBanner.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PaIconName } from '../PaIcon/PaIcon.vue'\n\nexport type PaBannerVariant =\n | 'info'\n | 'info-dark'\n | 'success'\n | 'warning'\n | 'error'\n\nexport interface PaBannerProps {\n variant?: PaBannerVariant\n title: string\n label?: string\n}\n\nexport const VARIANT_ICONS: Record<PaBannerVariant, PaIconName> = {\n 'info': 'info',\n 'info-dark': 'info',\n 'success': 'check-circle',\n 'warning': 'warning-circle',\n 'error': 'warning',\n}\n\nexport const VARIANT_A11Y: Record<\n PaBannerVariant,\n { role: 'status' | 'alert'; ariaLive: 'polite' | 'assertive' }\n> = {\n 'info': { role: 'status', ariaLive: 'polite' },\n 'info-dark': { role: 'status', ariaLive: 'polite' },\n 'success': { role: 'status', ariaLive: 'polite' },\n 'warning': { role: 'alert', ariaLive: 'assertive' },\n 'error': { role: 'alert', ariaLive: 'assertive' },\n}\n\nexport const VARIANT_LABELS: Record<PaBannerVariant, string> = {\n 'info': 'Avviso',\n 'info-dark': 'Avviso scuro',\n 'success': 'Notifica di successo',\n 'warning': 'Attenzione',\n 'error': 'Errore',\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useId } from 'vue'\nimport PaIcon from '../PaIcon/PaIcon.vue'\n\nconst props = withDefaults(defineProps<PaBannerProps>(), {\n variant: 'info',\n label: undefined,\n})\n\nconst titleId = `pa-banner-${useId()}__title`\n\nconst resolvedLabel = computed(() => props.label ?? VARIANT_LABELS[props.variant])\nconst resolvedA11y = computed(() => VARIANT_A11Y[props.variant])\nconst resolvedIcon = computed(() => VARIANT_ICONS[props.variant])\n</script>\n\n<template>\n <aside :class=\"['pa-banner', `pa-banner--${variant}`]\"\n :role=\"resolvedA11y.role\"\n :aria-live=\"resolvedA11y.ariaLive\"\n :aria-labelledby=\"titleId\"\n :aria-label=\"resolvedLabel\">\n <div class=\"pa-banner__container\">\n <div class=\"pa-banner__icon pa-banner__icon--leading\">\n <PaIcon :name=\"resolvedIcon\"\n size=\"lg\" />\n </div>\n <div class=\"pa-banner__content\">\n <div class=\"pa-banner__title-row\">\n <div class=\"pa-banner__icon pa-banner__icon--inline\">\n <PaIcon :name=\"resolvedIcon\"\n size=\"lg\" />\n </div>\n <h3 :id=\"titleId\"\n class=\"pa-banner__title\">{{ title }}</h3>\n </div>\n <div class=\"pa-banner__body\">\n <slot />\n </div>\n </div>\n <div v-if=\"$slots.action\"\n class=\"pa-banner__action\">\n <slot name=\"action\" />\n </div>\n </div>\n </aside>\n</template>\n\n<style scoped>\n.pa-banner {\n container-type: inline-size;\n font-family: var(--pa-font-family-base);\n border-radius: var(--pa-radius-smooth);\n background: var(--pa-banner-bg);\n color: var(--pa-banner-text);\n\n --pa-banner-bg: var(--pa-color-bg-primary-light-40);\n --pa-banner-text: var(--pa-color-text-secondary-gray);\n --pa-banner-body: var(--pa-color-text-black);\n --pa-banner-link: var(--pa-color-primary);\n --pa-banner-icon-color: var(--pa-color-text-secondary-gray);\n}\n\n.pa-banner__container {\n max-width: 1172px;\n margin: 0 auto;\n padding: var(--pa-space-md) var(--pa-space-2xl);\n display: flex;\n align-items: center;\n box-sizing: border-box;\n}\n\n.pa-banner__icon {\n color: var(--pa-banner-icon-color);\n display: flex;\n align-items: center;\n}\n\n.pa-banner__icon--leading {\n padding-right: var(--pa-space-md);\n}\n\n.pa-banner__icon--inline {\n display: none;\n}\n\n.pa-banner__content {\n flex: 1 1 0;\n min-width: 0;\n}\n\n.pa-banner__action {\n display: flex;\n align-items: center;\n justify-content: center;\n padding-left: var(--pa-space-2xl);\n}\n\n.pa-banner__title {\n margin: 0;\n font-size: var(--pa-font-h4-size);\n line-height: var(--pa-font-h4-line-height);\n font-weight: var(--pa-font-h4-weight);\n letter-spacing: var(--pa-font-h4-letter-spacing);\n color: var(--pa-banner-text);\n}\n\n.pa-banner__body {\n margin-top: var(--pa-space-xs);\n font-size: var(--pa-font-body-size);\n line-height: var(--pa-font-body-line-height);\n font-weight: var(--pa-font-body-weight);\n color: var(--pa-banner-body);\n}\n\n.pa-banner__body :deep(a) {\n color: var(--pa-banner-link);\n text-decoration: underline;\n}\n\n.pa-banner--info-dark {\n --pa-banner-bg: var(--pa-color-bg-primary-dark-115);\n --pa-banner-text: var(--pa-color-text-white);\n --pa-banner-body: var(--pa-color-text-white);\n --pa-banner-link: var(--pa-color-accent);\n --pa-banner-icon-color: var(--pa-color-text-white);\n}\n\n.pa-banner--success {\n --pa-banner-icon-color: var(--pa-color-success);\n}\n\n.pa-banner--warning {\n --pa-banner-icon-color: var(--pa-color-warning);\n}\n\n.pa-banner--error {\n --pa-banner-icon-color: var(--pa-color-error);\n}\n\n@container (max-width: 600px) {\n .pa-banner {\n border-radius: 0;\n }\n\n .pa-banner__container {\n flex-direction: column;\n align-items: stretch;\n gap: 0;\n padding: var(--pa-space-md);\n }\n\n .pa-banner__icon--leading {\n display: none;\n }\n\n .pa-banner__icon--inline {\n display: flex;\n }\n\n .pa-banner__title-row {\n display: flex;\n align-items: center;\n gap: var(--pa-space-md);\n }\n\n .pa-banner__body {\n margin-top: var(--pa-space-md);\n }\n\n .pa-banner__action {\n display: block;\n width: 100%;\n padding-left: 0;\n margin-top: var(--pa-space-md);\n }\n\n .pa-banner__action :deep(.pa-button) {\n width: 100%;\n }\n}\n</style>\n"],"names":["VARIANT_ICONS","VARIANT_A11Y","VARIANT_LABELS","props","__props","titleId","useId","resolvedLabel","computed","resolvedA11y","resolvedIcon","_createElementBlock","_createElementVNode","_hoisted_2","_hoisted_3","_createVNode","PaIcon","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_renderSlot","_ctx","$slots","_openBlock","_hoisted_8"],"mappings":";;;;;GAgBaA,IAAqD;AAAA,EAChE,MAAQ;AAAA,EACR,aAAa;AAAA,EACb,SAAW;AAAA,EACX,SAAW;AAAA,EACX,OAAS;AACX,GAEaC,IAGT;AAAA,EACF,MAAQ,EAAE,MAAM,UAAU,UAAU,SAAA;AAAA,EACpC,aAAa,EAAE,MAAM,UAAU,UAAU,SAAA;AAAA,EACzC,SAAW,EAAE,MAAM,UAAU,UAAU,SAAA;AAAA,EACvC,SAAW,EAAE,MAAM,SAAS,UAAU,YAAA;AAAA,EACtC,OAAS,EAAE,MAAM,SAAS,UAAU,YAAA;AACtC,GAEaC,IAAkD;AAAA,EAC7D,MAAQ;AAAA,EACR,aAAa;AAAA,EACb,SAAW;AAAA,EACX,SAAW;AAAA,EACX,OAAS;AACX;;;;;;;;AAOA,UAAMC,IAAQC,GAKRC,IAAU,aAAaC,EAAA,CAAO,WAE9BC,IAAgBC,EAAS,MAAML,EAAM,SAASD,EAAeC,EAAM,OAAO,CAAC,GAC3EM,IAAeD,EAAS,MAAMP,EAAaE,EAAM,OAAO,CAAC,GACzDO,IAAeF,EAAS,MAAMR,EAAcG,EAAM,OAAO,CAAC;2BAI9DQ,EA4BQ,SAAA;AAAA,MA5BA,qCAAmCP,EAAA,OAAO,EAAA,CAAA;AAAA,MAC1C,MAAMK,EAAA,MAAa;AAAA,MACnB,aAAWA,EAAA,MAAa;AAAA,MACxB,mBAAiBJ;AAAA,MACjB,cAAYE,EAAA;AAAA,IAAA;MAClBK,EAsBM,OAtBNC,GAsBM;AAAA,QArBJD,EAGM,OAHNE,GAGM;AAAA,UAFJC,EACoBC,GAAA;AAAA,YADX,MAAMN,EAAA;AAAA,YACP,MAAK;AAAA,UAAA;;QAEfE,EAYM,OAZNK,GAYM;AAAA,UAXJL,EAOM,OAPNM,GAOM;AAAA,YANJN,EAGM,OAHNO,GAGM;AAAA,cAFJJ,EACoBC,GAAA;AAAA,gBADX,MAAMN,EAAA;AAAA,gBACP,MAAK;AAAA,cAAA;;YAEfE,EAC6C,MAAA;AAAA,cADxC,IAAIP;AAAA,cACL,OAAM;AAAA,YAAA,KAAsBD,EAAA,KAAK,GAAA,CAAA;AAAA,UAAA;UAEvCQ,EAEM,OAFNQ,GAEM;AAAA,YADJC,EAAQC,EAAA,QAAA,WAAA,CAAA,GAAA,QAAA,EAAA;AAAA,UAAA;;QAGDC,EAAAA,OAAO,UAAlBC,KAAAb,EAGM,OAHNc,GAGM;AAAA,UADJJ,EAAsBC,EAAA,QAAA,UAAA,CAAA,GAAA,QAAA,EAAA;AAAA,QAAA;;;;;"}
|