@12-apps/storage 2.3.0 → 2.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@12-apps/storage",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
4
4
  "type": "module",
5
5
  "description": "Image uploads that land at YOUR OWN ORIGIN, never at the bucket (12-20). Isomorphic core (format allowlist, upload ceiling, object-key grammar, rendition set, refusal taxonomy, wire schemas), host-mounted backend surface (./server: createApiStorage, the local-disk driver, the image-pipeline port, the orphan reclaim), Hono adapter (./hono), the S3-compatible driver behind its own subpath (./s3) and the bound picker + upload hook (./react). Standardized adoption contract in ADOPTING.md.",
6
6
  "exports": {
@@ -43,7 +43,7 @@
43
43
  }
44
44
  },
45
45
  "dependencies": {
46
- "@12-apps/ui": "^6.4.0",
46
+ "@12-apps/ui": "^6.8.0",
47
47
  "zod": "^4.3.5"
48
48
  },
49
49
  "devDependencies": {
@@ -86,6 +86,7 @@ export function createWebStorage(config: WebStorageConfig): WebStorage {
86
86
  onChange={setImageKey}
87
87
  label={messages.fieldLabel}
88
88
  removeLabel={messages.fieldRemove}
89
+ uploadCopy={messages.field}
89
90
  helperText={messages.fieldHelper}
90
91
  />
91
92
  </Stack>
@@ -1,3 +1,5 @@
1
+ import type { UploadButtonCopy } from '@12-apps/ui/copy';
2
+
1
3
  import { ACCEPTED_CONTENT_TYPES } from '../content-types';
2
4
  import { megabytes } from '../limits';
3
5
 
@@ -109,6 +111,15 @@ export interface WebStorageMessages {
109
111
  fieldLabel: string;
110
112
  fieldHelper: string;
111
113
  fieldRemove: string;
114
+ /**
115
+ * What the dropzone ITSELF says — its hint line, its accessible name, and
116
+ * the three announcements only a screen reader receives. `@12-apps/ui` stopped
117
+ * shipping English defaults for these, so a host that answers `fieldLabel`
118
+ * and nothing else would have a dropzone with no name and a silent progress
119
+ * bar. `buttonLabel` is unused here: `ImageField` passes `fieldLabel` as the
120
+ * override, because the field's own label is the one a form already names.
121
+ */
122
+ field: UploadButtonCopy;
112
123
  }
113
124
 
114
125
  /** Copy that only makes sense with the configured ceiling in it. */
@@ -5,6 +5,7 @@ import { Box } from '@12-apps/ui/mui/Box';
5
5
  import { Stack } from '@12-apps/ui/mui/Stack';
6
6
  import { Text } from '@12-apps/ui/typography/Text';
7
7
  import { Button } from '@12-apps/ui/form/Button';
8
+ import type { UploadButtonCopy } from '@12-apps/ui/copy';
8
9
  import { UploadButton } from '@12-apps/ui/form/UploadButton';
9
10
 
10
11
  import { ACCEPTED_CONTENT_TYPES } from '../content-types';
@@ -38,6 +39,13 @@ export interface ImageFieldProps {
38
39
  label: string;
39
40
  /** The button that clears a chosen image. REQUIRED, for the same reason. */
40
41
  removeLabel: string;
42
+ /**
43
+ * What the dropzone itself says — the hint under the label, its accessible
44
+ * name, and the three announcements only a screen reader receives. REQUIRED:
45
+ * `@12-apps/ui` ships no default copy, so without this the dropzone has no
46
+ * name and a silent progress bar.
47
+ */
48
+ uploadCopy: UploadButtonCopy;
41
49
  helperText?: string;
42
50
  /** Passed through per upload — `{ optimize: false }` for a rendered canvas. */
43
51
  uploadOptions?: UploadOptions;
@@ -92,6 +100,9 @@ export function ImageField(props: BoundImageFieldProps): JSX.Element {
92
100
  ) : null}
93
101
  <UploadButton
94
102
  variant="dropzone"
103
+ copy={props.uploadCopy}
104
+ // The field's own label wins over `uploadCopy.buttonLabel`: a form
105
+ // already names this field, and naming it twice is how the two drift.
95
106
  label={props.label}
96
107
  accept={ACCEPT}
97
108
  disabled={props.disabled || uploader.uploading}
@@ -35,5 +35,18 @@ export function PT_BR_WEB_STORAGE_MESSAGES(
35
35
  fieldLabel: 'Foto do produto',
36
36
  fieldHelper: 'A imagem é reduzida no navegador antes do envio.',
37
37
  fieldRemove: 'Remover imagem',
38
+ field: {
39
+ // `buttonLabel` is never read here — `ImageField` overrides it with
40
+ // `fieldLabel`. It is still answered, because the type is the whole of
41
+ // what `UploadButton` may render and a partial answer is not a pack.
42
+ buttonLabel: 'Foto do produto',
43
+ dropzoneHint: 'Solte a imagem aqui ou clique para escolher',
44
+ dropzoneRole: (label) => `Área de upload de imagem. ${label}`,
45
+ uploading: 'Enviando…',
46
+ dropReady: 'Imagem pronta para soltar',
47
+ percentUploaded: (percent) => `${percent}% enviado`,
48
+ uploadInProgress: (percent) => `Envio em andamento: ${percent}%`,
49
+ errorAnnouncement: (message) => `Erro: ${message}`,
50
+ },
38
51
  };
39
52
  }