@ozankurt/file-chips 1.0.0 → 1.1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.0
4
+
5
+ - `@fileChipsStyles` and `@fileChipsScripts` add the published file's modification time as `?v=`, and the script tag carries the Vite CSP nonce.
6
+ - TypeScript declarations (`dist/file-chips.d.ts`), including the `file-chips:change` event.
7
+ - CI tests Laravel 11, 12 and 13.
8
+
3
9
  ## 1.0.0
4
10
 
5
11
  - Initial release: framework-free file chips with a preview popover and mark-for-removal (`@ozankurt/file-chips` on npm), and a Laravel `<x-file-chips>` Blade component with optional Spatie Media Library support (`ozankurt/laravel-file-chips`).
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Compact file chips for forms and detail pages. Each chip opens a preview popover with a thumbnail, file details and View / Download links, and can mark the file for removal: a hidden input is added to your form and your server deletes the file on save.
4
4
 
5
+ ![An expense claim form with six file chips; the chip for client-dinner-receipt.jpg has opened a popover with a receipt thumbnail, the file size and date, a note, and View, Download and Remove on save buttons.](docs/images/popover-light.png)
6
+
5
7
  - **JavaScript + CSS** on npm as [`@ozankurt/file-chips`](https://www.npmjs.com/package/@ozankurt/file-chips): no dependencies, no framework, about 3 KB minified.
6
8
  - **Laravel** on Packagist as `ozankurt/laravel-file-chips`: a `<x-file-chips>` Blade component that renders the markup, with optional [Spatie Media Library](https://spatie.be/docs/laravel-medialibrary) support, and ships the same built JS and CSS.
7
9
 
@@ -26,6 +28,8 @@ In your layout:
26
28
  </body>
27
29
  ```
28
30
 
31
+ Both URLs carry the published file's modification time (`?v=...`), so browsers fetch the new files after you upgrade and publish the assets again. The script tag gets your CSP nonce when the app uses `Vite::useCspNonce()`.
32
+
29
33
  In a form:
30
34
 
31
35
  ```blade
@@ -46,6 +50,10 @@ foreach ($request->input('delete_media_ids', []) as $id) {
46
50
 
47
51
  Always scope the deletion to the owning model as above; the ids come from the browser.
48
52
 
53
+ Marking a file adds the hidden input and strikes the chip through until the form is saved:
54
+
55
+ ![The PDF chip is outlined in red with its name struck through, and its popover shows a red Marked button.](docs/images/marked-light.png)
56
+
49
57
  ### Props
50
58
 
51
59
  | Prop | Type | Default | Description |
@@ -184,6 +192,8 @@ Every colour, radius and size is a CSS custom property. Override them on `:root`
184
192
  }
185
193
  ```
186
194
 
195
+ ![The same form and popover in a dark theme set only through the custom properties above.](docs/images/popover-dark.png)
196
+
187
197
  Full list: `--fc-font-size`, `--fc-gap`, `--fc-radius`, `--fc-chip-max-width`, `--fc-chip-bg`, `--fc-chip-bg-hover`, `--fc-border`, `--fc-text`, `--fc-muted`, `--fc-danger`, `--fc-danger-bg`, `--fc-primary`, `--fc-primary-text`, `--fc-focus`, `--fc-ext-bg`, `--fc-popover-width`, `--fc-popover-bg`, `--fc-popover-border`, `--fc-popover-radius`, `--fc-popover-shadow`, `--fc-popover-z`, `--fc-thumb-size`, `--fc-thumb-bg`.
188
198
 
189
199
  ## Development
@@ -193,8 +203,19 @@ npm install && composer install
193
203
  npm test # JS (Vitest + happy-dom)
194
204
  vendor/bin/pest # PHP
195
205
  npm run build # rebuild dist/, which is committed
206
+ npm run examples # the showcase on http://localhost:5183/showcase.html
207
+ npm run screenshots # recapture docs/images/ from the showcase
208
+ npm run typecheck # the TypeScript declarations
196
209
  ```
197
210
 
211
+ CI runs the PHP suite on PHP 8.3 with Laravel 11, and PHP 8.4 with Laravel 12 and 13, plus the JS tests, the typecheck and a check that the committed `dist/` matches the sources.
212
+
213
+ ### TypeScript
214
+
215
+ `dist/file-chips.d.ts` types the JS API and the `file-chips:change` event, so `import FileChips from '@ozankurt/file-chips'` is typed in TypeScript and editors.
216
+
217
+ The showcase takes `?scheme=light|dark` and `?scene=popover|marked`.
218
+
198
219
  ## License
199
220
 
200
221
  MIT
@@ -0,0 +1,43 @@
1
+ // Type declarations for @ozankurt/file-chips.
2
+
3
+ export interface InitOptions {
4
+ /** Handle chips inside this element only. Default: the whole document. */
5
+ root?: Document | Element;
6
+ }
7
+
8
+ /** Detail of the bubbling `file-chips:change` event dispatched on a chip. */
9
+ export interface FileChipChangeDetail {
10
+ id: string;
11
+ input: string;
12
+ marked: boolean;
13
+ }
14
+
15
+ /**
16
+ * Start handling chips inside `root`. A root that is already handled, itself
17
+ * or through an ancestor, is a no-op. Returns a function that stops handling it.
18
+ */
19
+ export declare function init(options?: InitOptions): () => void;
20
+ export declare function close(): void;
21
+ export declare function getOpen(): HTMLElement | null;
22
+ export declare function position(chip: HTMLElement, popover: HTMLElement): void;
23
+
24
+ declare const FileChips: {
25
+ init: typeof init;
26
+ /** Open a chip's popover; returns the popover, or null when it has none. */
27
+ open(chip: HTMLElement): HTMLElement | null;
28
+ close: typeof close;
29
+ getOpen: typeof getOpen;
30
+ position: typeof position;
31
+ };
32
+
33
+ export default FileChips;
34
+
35
+ declare global {
36
+ interface HTMLElementEventMap {
37
+ 'file-chips:change': CustomEvent<FileChipChangeDetail>;
38
+ }
39
+
40
+ interface DocumentEventMap {
41
+ 'file-chips:change': CustomEvent<FileChipChangeDetail>;
42
+ }
43
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ozankurt/file-chips",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Compact file chips with a preview popover and mark-for-removal, framework-free",
5
5
  "keywords": [
6
6
  "file",
@@ -25,10 +25,12 @@
25
25
  "type": "module",
26
26
  "main": "dist/file-chips.cjs",
27
27
  "module": "dist/esm/file-chips.mjs",
28
+ "types": "dist/file-chips.d.ts",
28
29
  "unpkg": "dist/file-chips.min.js",
29
30
  "jsdelivr": "dist/file-chips.min.js",
30
31
  "exports": {
31
32
  ".": {
33
+ "types": "./dist/file-chips.d.ts",
32
34
  "import": "./dist/esm/file-chips.mjs",
33
35
  "require": "./dist/file-chips.cjs",
34
36
  "default": "./dist/esm/file-chips.mjs"
@@ -53,14 +55,20 @@
53
55
  "scripts": {
54
56
  "build": "node ./scripts/build.js",
55
57
  "test": "vitest run",
56
- "prepublishOnly": "npm test && npm run build"
58
+ "prepublishOnly": "npm test && npm run typecheck && npm run build",
59
+ "examples": "vite --config vite.examples.config.js",
60
+ "screenshots": "node scripts/screenshots.js",
61
+ "typecheck": "tsc -p tsconfig.types.json"
57
62
  },
58
63
  "publishConfig": {
59
64
  "access": "public"
60
65
  },
61
66
  "devDependencies": {
67
+ "@playwright/test": "1.63.0",
62
68
  "esbuild": "^0.28.2",
63
69
  "happy-dom": "^21.0.3",
70
+ "typescript": "^5.9.3",
71
+ "vite": "8.3.4",
64
72
  "vitest": "^5.0.5"
65
73
  }
66
74
  }