@bluevolt-tech/lumen 1.3.2
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 +286 -0
- package/assets/fonts/fonts.css +25 -0
- package/assets/icons/.gitkeep +0 -0
- package/assets/icons/edit.svg +3 -0
- package/assets/images/.gitkeep +0 -0
- package/assets/images/bluevolt-logo.png +0 -0
- package/dist/assets/fonts/fonts.css +25 -0
- package/dist/assets/icons/.gitkeep +0 -0
- package/dist/assets/icons/edit.svg +3 -0
- package/dist/assets/images/.gitkeep +0 -0
- package/dist/assets/images/bluevolt-logo.png +0 -0
- package/dist/components/bv-avatar/bv-avatar.d.ts +13 -0
- package/dist/components/bv-avatar/bv-avatar.js +81 -0
- package/dist/components/bv-badge/bv-badge.d.ts +11 -0
- package/dist/components/bv-badge/bv-badge.js +58 -0
- package/dist/components/bv-button/bv-button.d.ts +23 -0
- package/dist/components/bv-button/bv-button.js +395 -0
- package/dist/components/bv-category-pill/bv-category-pill.d.ts +11 -0
- package/dist/components/bv-category-pill/bv-category-pill.js +61 -0
- package/dist/components/bv-checkbox/bv-checkbox.d.ts +14 -0
- package/dist/components/bv-checkbox/bv-checkbox.js +89 -0
- package/dist/components/bv-chip/bv-chip.d.ts +11 -0
- package/dist/components/bv-chip/bv-chip.js +72 -0
- package/dist/components/bv-course-detail/bv-course-detail.d.ts +28 -0
- package/dist/components/bv-course-detail/bv-course-detail.js +269 -0
- package/dist/components/bv-course-detail-modal/bv-course-detail-modal.d.ts +35 -0
- package/dist/components/bv-course-detail-modal/bv-course-detail-modal.js +1455 -0
- package/dist/components/bv-course-grid-card/bv-course-grid-card.d.ts +12 -0
- package/dist/components/bv-course-grid-card/bv-course-grid-card.js +578 -0
- package/dist/components/bv-course-list-card/bv-course-list-card.d.ts +12 -0
- package/dist/components/bv-course-list-card/bv-course-list-card.js +585 -0
- package/dist/components/bv-course-outline/bv-course-outline.d.ts +49 -0
- package/dist/components/bv-course-outline/bv-course-outline.js +488 -0
- package/dist/components/bv-empty-state/bv-empty-state.d.ts +10 -0
- package/dist/components/bv-empty-state/bv-empty-state.js +69 -0
- package/dist/components/bv-filter-dropdown/bv-filter-dropdown.d.ts +26 -0
- package/dist/components/bv-filter-dropdown/bv-filter-dropdown.js +164 -0
- package/dist/components/bv-filter-panel/bv-filter-panel.d.ts +25 -0
- package/dist/components/bv-filter-panel/bv-filter-panel.js +222 -0
- package/dist/components/bv-icon/bv-icon.d.ts +10 -0
- package/dist/components/bv-icon/bv-icon.js +122 -0
- package/dist/components/bv-icon/icons.d.ts +3 -0
- package/dist/components/bv-modal/bv-modal.d.ts +13 -0
- package/dist/components/bv-modal/bv-modal.js +104 -0
- package/dist/components/bv-page-title/bv-page-title.d.ts +4 -0
- package/dist/components/bv-page-title/bv-page-title.js +33 -0
- package/dist/components/bv-pagination/bv-pagination.d.ts +20 -0
- package/dist/components/bv-pagination/bv-pagination.js +139 -0
- package/dist/components/bv-portal-header/bv-portal-header.d.ts +12 -0
- package/dist/components/bv-portal-header/bv-portal-header.js +854 -0
- package/dist/components/bv-portal-layout/bv-portal-layout.d.ts +6 -0
- package/dist/components/bv-portal-layout/bv-portal-layout.js +39 -0
- package/dist/components/bv-progress-bar/bv-progress-bar.d.ts +11 -0
- package/dist/components/bv-progress-bar/bv-progress-bar.js +61 -0
- package/dist/components/bv-promo-banner/bv-promo-banner.d.ts +12 -0
- package/dist/components/bv-promo-banner/bv-promo-banner.js +79 -0
- package/dist/components/bv-radio/bv-radio.d.ts +11 -0
- package/dist/components/bv-radio/bv-radio.js +78 -0
- package/dist/components/bv-searchbox/bv-searchbox.d.ts +10 -0
- package/dist/components/bv-searchbox/bv-searchbox.js +68 -0
- package/dist/components/bv-star-rating/bv-star-rating.d.ts +11 -0
- package/dist/components/bv-star-rating/bv-star-rating.js +67 -0
- package/dist/components/bv-table/bv-table.d.ts +5 -0
- package/dist/components/bv-table/bv-table.js +72 -0
- package/dist/components/bv-toggle/bv-toggle.d.ts +11 -0
- package/dist/components/bv-toggle/bv-toggle.js +72 -0
- package/dist/components/bv-user-row/bv-user-row.d.ts +12 -0
- package/dist/components/bv-user-row/bv-user-row.js +574 -0
- package/dist/components/bv-view-switcher/bv-view-switcher.d.ts +11 -0
- package/dist/components/bv-view-switcher/bv-view-switcher.js +91 -0
- package/dist/preview/index.html +76 -0
- package/dist/storybook/stories/screens/course-catalog.data.d.ts +28 -0
- package/dist/storybook/stories/screens/course-catalog.data.js +301 -0
- package/dist/themes/base.css +66 -0
- package/dist/themes/layouts.css +35 -0
- package/package.json +181 -0
- package/themes/base.css +66 -0
- package/themes/layouts.css +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# Lumen — BlueVolt Component Library
|
|
2
|
+
|
|
3
|
+
Lumen is BlueVolt's design system: a collection of framework-agnostic UI components built with native Web Components. Drop them into any app — vanilla JS, AngularJS, Angular, React, Vue — with no framework dependency.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Storybook
|
|
8
|
+
|
|
9
|
+
The Storybook is the source of truth for components. Each component page includes:
|
|
10
|
+
|
|
11
|
+
- Live interactive preview with all variants and states
|
|
12
|
+
- Full attribute reference
|
|
13
|
+
- Framework Code tab with copy-paste setup for **HTML/ASPX**, **AngularJS**, **Angular 11**, and **Angular 18**
|
|
14
|
+
|
|
15
|
+
Run it locally:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm run storybook
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
Install from GitHub Packages:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @bluevolt-tech/lumen
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Prerequisites
|
|
32
|
+
|
|
33
|
+
**1. Configure npm to authenticate with GitHub Packages**
|
|
34
|
+
|
|
35
|
+
Create or edit `~/.npmrc`:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
@bluevolt-tech:registry=https://npm.pkg.github.com
|
|
39
|
+
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Replace `YOUR_GITHUB_TOKEN` with a [GitHub personal access token](https://github.com/settings/tokens) that has `read:packages` scope.
|
|
43
|
+
|
|
44
|
+
**2. Load the Roboto font**
|
|
45
|
+
|
|
46
|
+
Lumen uses Roboto (weights 400, 500, 600, 700). Add to your app's `<head>`:
|
|
47
|
+
|
|
48
|
+
```html
|
|
49
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
50
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
51
|
+
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Quick Start
|
|
57
|
+
|
|
58
|
+
### Plain HTML / Vanilla JS
|
|
59
|
+
|
|
60
|
+
```html
|
|
61
|
+
<!DOCTYPE html>
|
|
62
|
+
<html>
|
|
63
|
+
<head>
|
|
64
|
+
<!-- 1. Base design tokens (colors, spacing, typography) -->
|
|
65
|
+
<link rel="stylesheet" href="node_modules/@bluevolt-tech/lumen/themes/base.css" />
|
|
66
|
+
|
|
67
|
+
<!-- 2. Load Roboto font (see Installation) -->
|
|
68
|
+
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
69
|
+
|
|
70
|
+
<!-- 3. Import components -->
|
|
71
|
+
<script type="module">
|
|
72
|
+
import '@bluevolt-tech/lumen/components/bv-button';
|
|
73
|
+
import '@bluevolt-tech/lumen/components/bv-badge';
|
|
74
|
+
</script>
|
|
75
|
+
</head>
|
|
76
|
+
<body>
|
|
77
|
+
<bv-button variant="primary">Save changes</bv-button>
|
|
78
|
+
<bv-badge variant="success">New</bv-badge>
|
|
79
|
+
</body>
|
|
80
|
+
</html>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Angular (18+)
|
|
84
|
+
|
|
85
|
+
**1. Install the package:**
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm install @bluevolt-tech/lumen
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**2. Add theme CSS to `angular.json`:**
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"projects": {
|
|
96
|
+
"your-app": {
|
|
97
|
+
"architect": {
|
|
98
|
+
"build": {
|
|
99
|
+
"options": {
|
|
100
|
+
"styles": [
|
|
101
|
+
"node_modules/@bluevolt-tech/lumen/themes/base.css",
|
|
102
|
+
"src/styles.css"
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**3. Enable custom elements in your component:**
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
116
|
+
import '@bluevolt-tech/lumen/components/bv-button';
|
|
117
|
+
import '@bluevolt-tech/lumen/components/bv-badge';
|
|
118
|
+
|
|
119
|
+
@Component({
|
|
120
|
+
selector: 'app-root',
|
|
121
|
+
standalone: true,
|
|
122
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
123
|
+
template: `
|
|
124
|
+
<bv-button variant="primary">Save changes</bv-button>
|
|
125
|
+
<bv-badge variant="success">New</bv-badge>
|
|
126
|
+
`
|
|
127
|
+
})
|
|
128
|
+
export class AppComponent {}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**4. Load Roboto font in `index.html`:**
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### AngularJS (1.x)
|
|
138
|
+
|
|
139
|
+
See the **Framework Code** tab in Storybook for the complete AngularJS setup with CDN links and controller bindings.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Using Screens with Mock Data
|
|
144
|
+
|
|
145
|
+
Lumen ships reference screen implementations with mock data. Import both the screen component and its data:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import '@bluevolt-tech/lumen/components/bv-portal-layout';
|
|
149
|
+
import '@bluevolt-tech/lumen/components/bv-portal-header';
|
|
150
|
+
import '@bluevolt-tech/lumen/components/bv-filter-panel';
|
|
151
|
+
// ... other screen components
|
|
152
|
+
|
|
153
|
+
import { mockData } from '@bluevolt-tech/lumen/storybook/stories/screens/course-catalog.data';
|
|
154
|
+
|
|
155
|
+
// Use mockData to populate the screen initially, then swap with real API calls
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The mock data shows the expected data shape for each screen. Once the layout renders correctly, replace it with your application's data source.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Theming
|
|
163
|
+
|
|
164
|
+
Include `themes/base.css` for the default BlueVolt theme. Override any token on `:root`:
|
|
165
|
+
|
|
166
|
+
```css
|
|
167
|
+
:root {
|
|
168
|
+
--bv-color-primary: #005fcc;
|
|
169
|
+
--bv-color-primary-dark: #004499;
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
| Category | Prefix | Example |
|
|
174
|
+
|------------|-------------------|-----------------------------------------------|
|
|
175
|
+
| Colors | `--bv-color-*` | `--bv-color-primary`, `--bv-color-danger` |
|
|
176
|
+
| Spacing | `--bv-spacing-*` | `--bv-spacing-sm` (8px), `--bv-spacing-md` (16px) |
|
|
177
|
+
| Typography | `--bv-font-*` | `--bv-font-size-sm`, `--bv-font-weight-bold` |
|
|
178
|
+
| Radius | `--bv-radius-*` | `--bv-radius-sm`, `--bv-radius-full` |
|
|
179
|
+
| Shadow | `--bv-shadow-*` | `--bv-shadow-sm`, `--bv-shadow-lg` |
|
|
180
|
+
| Transition | `--bv-transition-*` | `--bv-transition-fast`, `--bv-transition-slow` |
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Events
|
|
185
|
+
|
|
186
|
+
All components dispatch events with `{ bubbles: true, composed: true }` so they cross Shadow DOM boundaries and can be listened to on any ancestor element:
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
document.addEventListener('bv-page-change', (e) => {
|
|
190
|
+
console.log(e.detail.page);
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Browser Support
|
|
197
|
+
|
|
198
|
+
| Browser | Minimum Version |
|
|
199
|
+
|---------|----------------|
|
|
200
|
+
| Chrome | 67+ |
|
|
201
|
+
| Firefox | 63+ |
|
|
202
|
+
| Safari | 12.1+ |
|
|
203
|
+
| Edge | 79+ |
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Deployment
|
|
208
|
+
|
|
209
|
+
### Library — GitHub Packages
|
|
210
|
+
|
|
211
|
+
The npm package (`@bluevolt-tech/lumen`) is published to GitHub Packages. Publishing is triggered automatically by creating a GitHub release, which runs the `deploy.yml` workflow.
|
|
212
|
+
|
|
213
|
+
**Build pipeline:**
|
|
214
|
+
|
|
215
|
+
1. `npm run build:tokens` — Regenerates `themes/base.css` from token definitions
|
|
216
|
+
2. `npm run build:components` — Compiles TypeScript to JavaScript with CSS inlined
|
|
217
|
+
3. `npm run build:types` — Generates `.d.ts` TypeScript declaration files
|
|
218
|
+
4. `npm run build:static` — Copies themes, assets to `dist/`
|
|
219
|
+
5. `npm publish` — Publishes to GitHub Packages (triggered by `prepublishOnly` hook)
|
|
220
|
+
|
|
221
|
+
**What gets published:**
|
|
222
|
+
|
|
223
|
+
- `dist/` — Compiled JS + TypeScript declarations
|
|
224
|
+
- `themes/` — Generated CSS files (base.css, layouts.css)
|
|
225
|
+
- `assets/` — Static files (fonts.css, icons)
|
|
226
|
+
|
|
227
|
+
**Local testing before publish:**
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
npm run build # Full build
|
|
231
|
+
npm pack # Creates tarball
|
|
232
|
+
cd /path/to/test-project
|
|
233
|
+
npm install /path/to/lumen/@bluevolt-tech-lumen-1.0.0.tgz
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Storybook — Azure Blob Storage
|
|
237
|
+
|
|
238
|
+
The Storybook is hosted on Azure Blob Storage as a static website. Two deployments are maintained:
|
|
239
|
+
|
|
240
|
+
| URL path | Contents | Updated when |
|
|
241
|
+
|----------|----------|--------------|
|
|
242
|
+
| `/latest/` | Always the newest build | Every release |
|
|
243
|
+
| `/v{major}/` | Stable major version | On major/minor releases |
|
|
244
|
+
|
|
245
|
+
Deploying is triggered automatically by **publishing a GitHub release**. The `deploy.yml` workflow runs:
|
|
246
|
+
|
|
247
|
+
1. `npm run build` — generates tokens, compiles components, generates types
|
|
248
|
+
2. `npm run build-storybook -- --output-dir storybook-latest` with `STORYBOOK_BASE_PATH=/latest/` — bakes the base path into asset URLs for the blob subdirectory
|
|
249
|
+
3. Copies `dist/` into `storybook-latest/dist/` so component JS files are co-located with the Storybook
|
|
250
|
+
4. Uploads the output to Azure Blob Storage under `$web/latest`
|
|
251
|
+
5. Repeats steps 2–4 with `STORYBOOK_BASE_PATH=/v{major}/` for the versioned deployment
|
|
252
|
+
|
|
253
|
+
### Simulating the pipeline locally
|
|
254
|
+
|
|
255
|
+
To reproduce the exact production build before releasing:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# Step 1 — build tokens, compile components, generate types, copy static assets
|
|
259
|
+
npm run build
|
|
260
|
+
|
|
261
|
+
# Step 2 — build Storybook with /latest/ base path
|
|
262
|
+
# Windows Git Bash: MSYS_NO_PATHCONV=1 prevents path mangling of /latest/
|
|
263
|
+
MSYS_NO_PATHCONV=1 STORYBOOK_BASE_PATH=/latest/ npm run build-storybook -- --output-dir storybook-latest
|
|
264
|
+
|
|
265
|
+
# Step 3 — co-locate component JS (mirrors the pipeline cp step)
|
|
266
|
+
cp -r dist storybook-latest/dist
|
|
267
|
+
|
|
268
|
+
# Step 4 — serve under /latest/ to match blob structure
|
|
269
|
+
mkdir -p temp-serve/latest
|
|
270
|
+
cp -r storybook-latest/* temp-serve/latest/
|
|
271
|
+
npx http-server temp-serve -p 8080
|
|
272
|
+
# Open http://localhost:8080/latest/
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
> **Critical invariant:** `tokens/style-dictionary.config.cjs` must have `prefix: 'bv'`. This generates `--bv-*` CSS variables that components reference. If the prefix is wrong, all components render unstyled.
|
|
276
|
+
|
|
277
|
+
### How CSS tokens reach Storybook components
|
|
278
|
+
|
|
279
|
+
`storybook/.storybook/preview.ts` imports `themes/base.css` and `themes/layouts.css` directly. Vite bundles them into `assets/preview-*.css`, which is loaded inside the Storybook iframe. No separate `<link>` tags or script injection is needed.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Resources
|
|
284
|
+
|
|
285
|
+
- **Storybook** — component playground, API reference, and framework integration snippets (`npm run storybook`)
|
|
286
|
+
- Questions or issues → reach out to the Lumen team or open an issue in this repository
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Font loading for Lumen design system.
|
|
3
|
+
*
|
|
4
|
+
* CONSUMERS MUST LOAD ROBOTO FONT:
|
|
5
|
+
* The Lumen design system uses Roboto (weights 400, 500, 600, 700).
|
|
6
|
+
* Consumers are responsible for loading the font in their application.
|
|
7
|
+
*
|
|
8
|
+
* Recommended approach - Google Fonts CDN (add to your app's <head>):
|
|
9
|
+
* <link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10
|
+
* <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
|
+
* <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
12
|
+
*
|
|
13
|
+
* Alternative approach - self-host:
|
|
14
|
+
* Download from https://fonts.google.com/specimen/Roboto and serve from your own CDN.
|
|
15
|
+
*
|
|
16
|
+
* Font files are NOT bundled with this library to:
|
|
17
|
+
* - Keep package size small
|
|
18
|
+
* - Avoid licensing complexity
|
|
19
|
+
* - Allow consumers to use their existing font loading strategy
|
|
20
|
+
* - Prevent duplicate downloads when Roboto is already loaded
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
:root {
|
|
24
|
+
--bv-font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
|
|
25
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
2
|
+
<path d="M15.0002 8.33326L11.6669 4.99993M2.0835 17.9166L4.9038 17.6032C5.24838 17.5649 5.42067 17.5458 5.5817 17.4937C5.72457 17.4474 5.86054 17.3821 5.9859 17.2994C6.12721 17.2062 6.24978 17.0836 6.49493 16.8385L17.5002 5.83326C18.4207 4.91279 18.4207 3.4204 17.5002 2.49993C16.5797 1.57945 15.0873 1.57945 14.1669 2.49992L3.1616 13.5052C2.91645 13.7503 2.79388 13.8729 2.70069 14.0142C2.61802 14.1396 2.55268 14.2755 2.50642 14.4184C2.45429 14.5794 2.43515 14.7517 2.39686 15.0963L2.0835 17.9166Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
</svg>
|
|
File without changes
|
|
Binary file
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Font loading for Lumen design system.
|
|
3
|
+
*
|
|
4
|
+
* CONSUMERS MUST LOAD ROBOTO FONT:
|
|
5
|
+
* The Lumen design system uses Roboto (weights 400, 500, 600, 700).
|
|
6
|
+
* Consumers are responsible for loading the font in their application.
|
|
7
|
+
*
|
|
8
|
+
* Recommended approach - Google Fonts CDN (add to your app's <head>):
|
|
9
|
+
* <link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10
|
+
* <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
|
+
* <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
12
|
+
*
|
|
13
|
+
* Alternative approach - self-host:
|
|
14
|
+
* Download from https://fonts.google.com/specimen/Roboto and serve from your own CDN.
|
|
15
|
+
*
|
|
16
|
+
* Font files are NOT bundled with this library to:
|
|
17
|
+
* - Keep package size small
|
|
18
|
+
* - Avoid licensing complexity
|
|
19
|
+
* - Allow consumers to use their existing font loading strategy
|
|
20
|
+
* - Prevent duplicate downloads when Roboto is already loaded
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
:root {
|
|
24
|
+
--bv-font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
|
|
25
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
2
|
+
<path d="M15.0002 8.33326L11.6669 4.99993M2.0835 17.9166L4.9038 17.6032C5.24838 17.5649 5.42067 17.5458 5.5817 17.4937C5.72457 17.4474 5.86054 17.3821 5.9859 17.2994C6.12721 17.2062 6.24978 17.0836 6.49493 16.8385L17.5002 5.83326C18.4207 4.91279 18.4207 3.4204 17.5002 2.49993C16.5797 1.57945 15.0873 1.57945 14.1669 2.49992L3.1616 13.5052C2.91645 13.7503 2.79388 13.8729 2.70069 14.0142C2.61802 14.1396 2.55268 14.2755 2.50642 14.4184C2.45429 14.5794 2.43515 14.7517 2.39686 15.0963L2.0835 17.9166Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
</svg>
|
|
File without changes
|
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
2
|
+
export declare class BvAvatar extends HTMLElement {
|
|
3
|
+
static readonly observedAttributes: string[];
|
|
4
|
+
private _rendered;
|
|
5
|
+
private _img;
|
|
6
|
+
private _label;
|
|
7
|
+
constructor();
|
|
8
|
+
connectedCallback(): void;
|
|
9
|
+
attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
|
|
10
|
+
private _render;
|
|
11
|
+
private _syncSrc;
|
|
12
|
+
private _syncInitials;
|
|
13
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-avatar/bv-avatar.css
|
|
2
|
+
var bv_avatar_default = ":host {\n --bv-avatar-size: 40px;\n --bv-avatar-bg: var(--bv-color-primary-light);\n --bv-avatar-color: var(--bv-color-primary);\n --bv-avatar-radius: var(--bv-radius-full);\n display: inline-flex;\n}\n\n:host([size='xs']) {\n --bv-avatar-size: 24px;\n}\n:host([size='sm']) {\n --bv-avatar-size: 32px;\n}\n:host([size='md']) {\n --bv-avatar-size: 40px;\n}\n:host([size='lg']) {\n --bv-avatar-size: 48px;\n}\n:host([size='xl']) {\n --bv-avatar-size: 64px;\n}\n\n.avatar {\n width: var(--bv-avatar-size);\n height: var(--bv-avatar-size);\n border-radius: var(--bv-avatar-radius);\n background: var(--bv-avatar-bg);\n color: var(--bv-avatar-color);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n flex-shrink: 0;\n font-family: var(--bv-font-family-base);\n font-weight: var(--bv-font-weight-semibold);\n font-size: calc(var(--bv-avatar-size) * 0.38);\n user-select: none;\n}\n\n.avatar img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n}\n";
|
|
3
|
+
|
|
4
|
+
// components/bv-avatar/bv-avatar.ts
|
|
5
|
+
var BvAvatar = class extends HTMLElement {
|
|
6
|
+
static observedAttributes = ["src", "alt", "initials", "size"];
|
|
7
|
+
_rendered = false;
|
|
8
|
+
_img = null;
|
|
9
|
+
_label = null;
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
this.attachShadow({ mode: "open" });
|
|
13
|
+
if ("replaceSync" in CSSStyleSheet.prototype) {
|
|
14
|
+
const sheet = new CSSStyleSheet();
|
|
15
|
+
sheet.replaceSync(bv_avatar_default);
|
|
16
|
+
this.shadowRoot.adoptedStyleSheets = [sheet];
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
connectedCallback() {
|
|
20
|
+
this._render();
|
|
21
|
+
}
|
|
22
|
+
attributeChangedCallback(name, _old, val) {
|
|
23
|
+
if (!this._rendered) return;
|
|
24
|
+
if (name === "src") this._syncSrc(val);
|
|
25
|
+
if (name === "initials") this._syncInitials(val);
|
|
26
|
+
if (name === "alt" && this._img) this._img.alt = val ?? "";
|
|
27
|
+
}
|
|
28
|
+
_render() {
|
|
29
|
+
if (this._rendered) return;
|
|
30
|
+
this._rendered = true;
|
|
31
|
+
const shadow = this.shadowRoot;
|
|
32
|
+
if (!shadow.adoptedStyleSheets.length) {
|
|
33
|
+
const s = document.createElement("style");
|
|
34
|
+
s.textContent = bv_avatar_default;
|
|
35
|
+
shadow.appendChild(s);
|
|
36
|
+
}
|
|
37
|
+
const div = document.createElement("div");
|
|
38
|
+
div.className = "avatar";
|
|
39
|
+
const src = this.getAttribute("src");
|
|
40
|
+
if (src) {
|
|
41
|
+
this._img = document.createElement("img");
|
|
42
|
+
this._img.src = src;
|
|
43
|
+
this._img.alt = this.getAttribute("alt") ?? "";
|
|
44
|
+
div.appendChild(this._img);
|
|
45
|
+
} else {
|
|
46
|
+
this._label = document.createElement("span");
|
|
47
|
+
this._label.textContent = this.getAttribute("initials") ?? "";
|
|
48
|
+
div.appendChild(this._label);
|
|
49
|
+
}
|
|
50
|
+
shadow.appendChild(div);
|
|
51
|
+
}
|
|
52
|
+
_syncSrc(src) {
|
|
53
|
+
var _a, _b;
|
|
54
|
+
const div = this.shadowRoot.querySelector(".avatar");
|
|
55
|
+
if (src) {
|
|
56
|
+
if (!this._img) {
|
|
57
|
+
this._img = document.createElement("img");
|
|
58
|
+
this._img.alt = this.getAttribute("alt") ?? "";
|
|
59
|
+
(_a = this._label) == null ? void 0 : _a.remove();
|
|
60
|
+
this._label = null;
|
|
61
|
+
div.appendChild(this._img);
|
|
62
|
+
}
|
|
63
|
+
this._img.src = src;
|
|
64
|
+
} else {
|
|
65
|
+
(_b = this._img) == null ? void 0 : _b.remove();
|
|
66
|
+
this._img = null;
|
|
67
|
+
this._label = document.createElement("span");
|
|
68
|
+
this._label.textContent = this.getAttribute("initials") ?? "";
|
|
69
|
+
div.appendChild(this._label);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
_syncInitials(val) {
|
|
73
|
+
if (this._label) this._label.textContent = val ?? "";
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
if (!customElements.get("bv-avatar")) {
|
|
77
|
+
customElements.define("bv-avatar", BvAvatar);
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
BvAvatar
|
|
81
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type BadgeVariant = 'default' | 'primary' | 'success' | 'warning' | 'danger';
|
|
2
|
+
export type BadgeSize = 'sm' | 'md' | 'lg';
|
|
3
|
+
export declare class BvBadge extends HTMLElement {
|
|
4
|
+
static readonly observedAttributes: string[];
|
|
5
|
+
private _rendered;
|
|
6
|
+
constructor();
|
|
7
|
+
connectedCallback(): void;
|
|
8
|
+
attributeChangedCallback(): void;
|
|
9
|
+
private _render;
|
|
10
|
+
private _update;
|
|
11
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-badge/bv-badge.css
|
|
2
|
+
var bv_badge_default = ":host {\n --bv-badge-bg: var(--bv-color-neutral-200);\n --bv-badge-color: var(--bv-color-neutral-700);\n display: inline-flex;\n}\n\n:host([variant='primary']) {\n --bv-badge-bg: var(--bv-color-primary-light);\n --bv-badge-color: var(--bv-color-primary);\n}\n:host([variant='success']) {\n --bv-badge-bg: var(--bv-color-success-light);\n --bv-badge-color: var(--bv-color-success);\n}\n:host([variant='warning']) {\n --bv-badge-bg: var(--bv-color-warning-light);\n --bv-badge-color: var(--bv-color-warning);\n}\n:host([variant='danger']) {\n --bv-badge-bg: var(--bv-color-danger-light);\n --bv-badge-color: var(--bv-color-danger);\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n border-radius: var(--bv-radius-full);\n background: var(--bv-badge-bg);\n color: var(--bv-badge-color);\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-xs);\n font-weight: var(--bv-font-weight-medium);\n line-height: 18px;\n white-space: nowrap;\n}\n\n:host([size='sm']) .badge {\n padding: 1px 6px;\n font-size: 11px;\n line-height: 16px;\n}\n\n:host([size='lg']) .badge {\n padding: 3px 10px;\n font-size: var(--bv-font-size-sm);\n line-height: 20px;\n}\n\n.dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentColor;\n flex-shrink: 0;\n}\n";
|
|
3
|
+
|
|
4
|
+
// components/bv-badge/bv-badge.ts
|
|
5
|
+
var BvBadge = class extends HTMLElement {
|
|
6
|
+
static observedAttributes = ["variant", "size", "dot"];
|
|
7
|
+
_rendered = false;
|
|
8
|
+
constructor() {
|
|
9
|
+
super();
|
|
10
|
+
this.attachShadow({ mode: "open" });
|
|
11
|
+
if ("replaceSync" in CSSStyleSheet.prototype) {
|
|
12
|
+
const sheet = new CSSStyleSheet();
|
|
13
|
+
sheet.replaceSync(bv_badge_default);
|
|
14
|
+
this.shadowRoot.adoptedStyleSheets = [sheet];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
connectedCallback() {
|
|
18
|
+
this._render();
|
|
19
|
+
}
|
|
20
|
+
attributeChangedCallback() {
|
|
21
|
+
if (this._rendered) this._update();
|
|
22
|
+
}
|
|
23
|
+
_render() {
|
|
24
|
+
if (this._rendered) return;
|
|
25
|
+
this._rendered = true;
|
|
26
|
+
const shadow = this.shadowRoot;
|
|
27
|
+
if (!shadow.adoptedStyleSheets.length) {
|
|
28
|
+
const s = document.createElement("style");
|
|
29
|
+
s.textContent = bv_badge_default;
|
|
30
|
+
shadow.appendChild(s);
|
|
31
|
+
}
|
|
32
|
+
const badge = document.createElement("span");
|
|
33
|
+
badge.className = "badge";
|
|
34
|
+
if (this.hasAttribute("dot")) {
|
|
35
|
+
const dot = document.createElement("span");
|
|
36
|
+
dot.className = "dot";
|
|
37
|
+
badge.appendChild(dot);
|
|
38
|
+
}
|
|
39
|
+
badge.appendChild(document.createElement("slot"));
|
|
40
|
+
shadow.appendChild(badge);
|
|
41
|
+
}
|
|
42
|
+
_update() {
|
|
43
|
+
const dot = this.shadowRoot.querySelector(".dot");
|
|
44
|
+
if (this.hasAttribute("dot") && !dot) {
|
|
45
|
+
const d = document.createElement("span");
|
|
46
|
+
d.className = "dot";
|
|
47
|
+
this.shadowRoot.querySelector(".badge").prepend(d);
|
|
48
|
+
} else if (!this.hasAttribute("dot") && dot) {
|
|
49
|
+
dot.remove();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
if (!customElements.get("bv-badge")) {
|
|
54
|
+
customElements.define("bv-badge", BvBadge);
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
BvBadge
|
|
58
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'danger' | 'ghost' | 'outline';
|
|
2
|
+
export type ButtonSize = 'sm' | 'md' | 'lg';
|
|
3
|
+
export type ButtonType = 'button' | 'submit' | 'reset';
|
|
4
|
+
export type ButtonIconPosition = 'left' | 'right';
|
|
5
|
+
export declare class BvButton extends HTMLElement {
|
|
6
|
+
static readonly observedAttributes: string[];
|
|
7
|
+
constructor();
|
|
8
|
+
get variant(): ButtonVariant;
|
|
9
|
+
set variant(value: ButtonVariant);
|
|
10
|
+
get size(): ButtonSize;
|
|
11
|
+
set size(value: ButtonSize);
|
|
12
|
+
get disabled(): boolean;
|
|
13
|
+
set disabled(value: boolean);
|
|
14
|
+
get loading(): boolean;
|
|
15
|
+
set loading(value: boolean);
|
|
16
|
+
get type(): ButtonType;
|
|
17
|
+
set type(value: ButtonType);
|
|
18
|
+
get fullWidth(): boolean;
|
|
19
|
+
set fullWidth(value: boolean);
|
|
20
|
+
connectedCallback(): void;
|
|
21
|
+
attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void;
|
|
22
|
+
private _render;
|
|
23
|
+
}
|