Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions frontend/purestack.studio/components/forms/appearance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
lucide_list,
lucide_list_ordered,
lucide_loader_circle,
lucide_trash_2,
lucide_trash,
lucide_underline,
lucide_x,
tabler_align_center,
Expand All @@ -52,7 +52,7 @@ const icons: Record<string, string> = {
'lucide:list': lucide_list,
'lucide:list-ordered': lucide_list_ordered,
'lucide:loader-circle': lucide_loader_circle,
'lucide:trash-2': lucide_trash_2,
'lucide:trash': lucide_trash,
'lucide:underline': lucide_underline,
'lucide:x': lucide_x,
'tabler:align-center': tabler_align_center,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ All eighteen supported treatments, shown in accent. Tone and variant are indepen
<DropFiles label="Reference files" hint="Images and PDF only"
emptyTitle="Add your references" emptyText="Choose files, drop them, or paste."
accept="image/*,.pdf" :multiple="true" :disabled="locked" :files="files"
uploadIcon="lucide:cloud-upload" fileIcon="lucide:file" removeIcon="lucide:trash-2"
uploadIcon="lucide:cloud-upload" fileIcon="lucide:file" removeIcon="lucide:trash"
:iconMap="fileIcons" :context="{ onChange: filesChanged }"/>
```

Expand Down Expand Up @@ -189,7 +189,7 @@ The drop zone opens the native picker with Enter or Space. File acceptance is a
<p>Fallback file icon when no type-specific mapping matches.</p>
</ApiProperty>

<ApiProperty anchor="drop-files-prop-removeIcon" name="removeIcon" valueType="RefOrValue&lt;string&gt;" defaultValue="lucide:trash-2">
<ApiProperty anchor="drop-files-prop-removeIcon" name="removeIcon" valueType="RefOrValue&lt;string&gt;" defaultValue="lucide:trash">
<p>Icon on each remove button.</p>
</ApiProperty>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
lucide_file_archive,
lucide_file_image,
lucide_file_text,
lucide_trash_2,
lucide_trash,
} from '@purestack/ts-svg-icons'
import {
type ComputedRef,
Expand Down Expand Up @@ -65,7 +65,7 @@ const dropFilesExampleTemplate = html`<Flex direction="column">
<DropFiles :files="referenceFiles" label="Design references" hint="Images and PDF files only."
emptyTitle="Add your references" emptyText="Choose files, drop them, or paste."
accept="image/*,.pdf" uploadIcon="lucide:file-image" fileIcon="lucide:file"
removeIcon="lucide:trash-2" :iconMap="fileIcons" :context="{ onChange: filesChanged }"/>
removeIcon="lucide:trash" :iconMap="fileIcons" :context="{ onChange: filesChanged }"/>
<FormStatus>{{ activity }}</FormStatus>
<ul><li r-for="file in referenceFiles">{{ file.name }} · {{ file.type || 'Unknown type' }} · {{ file.sizeLabel }} · {{ file.icon }}</li></ul>
</Flex>`
Expand Down Expand Up @@ -97,7 +97,7 @@ const component = defineComponent<DropFilesExample>(dropFilesExampleTemplate, {
const icons: Record<string, string> = {
'lucide:cloud-upload': lucide_cloud_upload,
'lucide:file': lucide_file,
'lucide:trash-2': lucide_trash_2,
'lucide:trash': lucide_trash,
'lucide:file-image': lucide_file_image,
'lucide:file-text': lucide_file_text,
'lucide:file-archive': lucide_file_archive,
Expand Down
2 changes: 1 addition & 1 deletion frontend/purestack.studio/guides/styling/icons.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ The lookup function throws for an unregistered name, so a missing icon causes an
| --- | --- |
| `FormSelectField`, `BtnGroup` drop-down | `lucide:chevron-down` |
| Autocomplete inputs | `lucide:chevron-down`, `lucide:loader-circle` while loading, `lucide:x` to remove a choice |
| `DropFiles` | `lucide:cloud-upload`, `lucide:file`, `lucide:trash-2`, and `lucide:file-image`, `lucide:file-text`, or `lucide:file-archive` for common file types |
| `DropFiles` | `lucide:cloud-upload`, `lucide:file`, `lucide:trash`, and `lucide:file-image`, `lucide:file-text`, or `lucide:file-archive` for common file types |
| `SignIn` | `lucide:log-in`, `tabler:user-filled` |
| Comparison and pricing features | `lucide:check`, `iconoir:check` |
| `Composer` toolbar | `lucide:bold`, `lucide:italic`, `lucide:underline`, `tabler:align-left`, `tabler:align-center`, `tabler:align-right`, `lucide:list`, `lucide:list-ordered`, `lucide:link`, `lucide:eraser`, `lucide:code` |
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"name": "purestack-repo",
"version": "1.1.12",
"version": "1.1.13",
"packageManager": "yarn@4.18.1",
"type": "module",
"sideEffects": false,
Expand Down
2 changes: 1 addition & 1 deletion packages/purestack/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "purestack",
"version": "1.1.12",
"version": "1.1.13",
"packageManager": "yarn@4.9.2",
"module": "./dist/purestack.mjs",
"types": "./dist/purestack.d.mts",
Expand Down
2 changes: 1 addition & 1 deletion packages/purestack/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const version: string = '1.1.12'
export const version: string = '1.1.13'

export * from '@purestack/ts-ssg'
2 changes: 1 addition & 1 deletion packages/ts-common/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@purestack/ts-common",
"version": "1.1.12",
"version": "1.1.13",
"packageManager": "yarn@4.9.2",
"module": "./dist/ts-common.mjs",
"types": "./dist/ts-common.d.mts",
Expand Down
2 changes: 1 addition & 1 deletion packages/ts-components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@purestack/ts-components",
"version": "1.1.12",
"version": "1.1.13",
"packageManager": "yarn@4.9.2",
"module": "./dist/ts-components.mjs",
"types": "./dist/ts-components.d.mts",
Expand Down
2 changes: 1 addition & 1 deletion packages/ts-components/src/standard/dropFiles/dropFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export interface DropFiles {

const DEFAULT_UPLOAD_ICON = 'lucide:cloud-upload'
const DEFAULT_FILE_ICON = 'lucide:file'
const DEFAULT_REMOVE_ICON = 'lucide:trash-2'
const DEFAULT_REMOVE_ICON = 'lucide:trash'

const DEFAULT_ICON_MAP: DropFilesIconMap = {
'image/*': 'lucide:file-image',
Expand Down
2 changes: 1 addition & 1 deletion packages/ts-css/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@purestack/ts-css",
"version": "1.1.12",
"version": "1.1.13",
"packageManager": "yarn@4.9.2",
"module": "./dist/ts-css.mjs",
"types": "./dist/ts-css.d.mts",
Expand Down
2 changes: 1 addition & 1 deletion packages/ts-html/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@purestack/ts-html",
"version": "1.1.12",
"version": "1.1.13",
"packageManager": "yarn@4.9.2",
"module": "./dist/ts-html.mjs",
"types": "./dist/ts-html.d.mts",
Expand Down
2 changes: 1 addition & 1 deletion packages/ts-minidom/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@purestack/ts-minidom",
"version": "1.1.12",
"version": "1.1.13",
"packageManager": "yarn@4.9.2",
"module": "./dist/ts-minidom.mjs",
"types": "./dist/ts-minidom.d.mts",
Expand Down
2 changes: 1 addition & 1 deletion packages/ts-page-scripts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@purestack/ts-page-scripts",
"version": "1.1.12",
"version": "1.1.13",
"packageManager": "yarn@4.9.2",
"module": "./dist/ts-page-scripts.mjs",
"types": "./dist/ts-page-scripts.d.mts",
Expand Down
2 changes: 1 addition & 1 deletion packages/ts-render/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@purestack/ts-render",
"version": "1.1.12",
"version": "1.1.13",
"packageManager": "yarn@4.9.2",
"module": "./dist/ts-render.mjs",
"types": "./dist/ts-render.d.mts",
Expand Down
2 changes: 1 addition & 1 deletion packages/ts-ssg-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "purestack-component-navigation",
"displayName": "PureStack Component Tools",
"description": "Component navigation, prop IntelliSense, lit-html syntax highlighting, and template formatting for Markdown, Regor MDX, and TypeScript templates.",
"version": "1.1.12",
"version": "1.1.13",
"private": true,
"publisher": "purestack",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/ts-ssg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ Add skins with a plugin's `skins` field. `themeSkins` in `@purestack/ts-style` h
- Regor MDX (`.mdx`, `.rmdx`): `remark-parse` + `remark-gfm` with Regor component markup preservation
- Plugin remark and rehype plugins, in plugin order
- HTML output via HAST + rehype
- `<import-codeblock src="./file.ts"/>` becomes a code block holding that file before compilation, anywhere a code block works; `src` resolves from the file the tag is in and must stay inside the content folder, and `lang` overrides the language inferred from the extension. Tags inside code stay as written, and the dev server re-renders the pages, headers, and footers that show a file when it changes.
- `<import-codeblock src="./file.ts"/>` becomes a code block holding that file before compilation, anywhere a code block works; `src` resolves from the file the tag is in and must stay inside the content folder, and `lang` overrides the language inferred from the extension. Both import tags register their files during rendering, including nested imports and imports in headers, footers, and generated pages. Full builds copy static assets after rendering and exclude these registered files. In lazy dev mode, an importing page's first render excludes its imports and removes any copies already in the output folder; removing the last import makes the file available as a static asset again after re-rendering. Tags inside code stay as written, and the dev server re-renders the pages, headers, and footers that show a file when it changes.
- H2/H3 outline extraction for page TOC
- Code highlighting with highlight.js or Shiki

Expand Down
2 changes: 1 addition & 1 deletion packages/ts-ssg/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@purestack/ts-ssg",
"version": "1.1.12",
"version": "1.1.13",
"packageManager": "yarn@4.9.2",
"module": "./dist/ts-ssg.mjs",
"types": "./dist/ts-ssg.d.mts",
Expand Down
11 changes: 9 additions & 2 deletions packages/ts-ssg/src/build/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ export interface StaticAssetBuildOptions {
getScriptCacheKey?: (relPath: string) => string | undefined
}

export interface CopyStaticAssetsOptions extends StaticAssetBuildOptions {
/** Already discovered assets selected by the build after rendering. */
files?: readonly StaticAssetFile[]
}

export interface CopyStaticAssetResult {
outPath: string
copied: boolean
Expand All @@ -29,10 +34,12 @@ export interface CopyStaticAssetResult {
export async function copyStaticAssets(
contentDir: string,
outDir: string,
options: StaticAssetBuildOptions = {},
options: CopyStaticAssetsOptions = {},
): Promise<CopyStaticAssetsResult> {
const log = getLogger()
const assets = await discoverStaticAssets(contentDir)
const assets = options.files
? [...options.files]
: await discoverStaticAssets(contentDir)
const tsDependencyIndex: Record<string, string[]> = {}
for (const asset of assets) {
const outPath = resolveStaticOutPath(outDir, asset, options)
Expand Down
5 changes: 3 additions & 2 deletions packages/ts-ssg/src/build/content-urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import { resolveRouteInfo } from '../routing/route'
const CONTENT_EXT_LIST = [...CONTENT_EXTS]

/**
* Every page and asset the build publishes from the content folder, keyed by
* posix source path, so content URLs are checked without touching the disk.
* Discovered pages and assets, keyed by posix source path, so content URLs are
* checked without touching the disk. Render-time copy exclusions are separate:
* an edit can replace an import with a link before its asset is copied again.
*/
export class ContentRouteIndex {
private readonly pagesByRelPath = new Map<string, ResolvedContentFile>()
Expand Down
3 changes: 3 additions & 0 deletions packages/ts-ssg/src/build/incremental/change-applier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface IncrementalChangeApplierInput {
scriptEntrypoints: ScriptEntrypointManager
persistManifest: () => Promise<void>
renderOnRequest: () => boolean
isGeneratedOutput: (relPath: string) => boolean
}

export class IncrementalChangeApplier {
Expand Down Expand Up @@ -275,6 +276,8 @@ export class IncrementalChangeApplier {
return
}

if (this.input.isGeneratedOutput(relPath)) return

const assetFile = toAssetFile(this.input.config.contentDir, relPath, ext)
const assetCopy = await copyStaticAsset(
this.input.config.contentDir,
Expand Down
18 changes: 16 additions & 2 deletions packages/ts-ssg/src/build/incremental/content-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ interface IncrementalContentStateInput {
renderOnRequest: () => boolean
persistManifest: () => Promise<void>
getManifest: () => BuildManifest
getAssetRelPaths: () => string[]
}

interface RebuildNavigatedContentInput {
Expand Down Expand Up @@ -110,6 +111,19 @@ export class IncrementalContentState {
this.dirtyPages.clear()
}

/** Dependencies registered while rendering pages, headers, and footers. */
getImportedFiles() {
const imported = new Set(this.input.context.partialImportedFiles)
for (const files of this.importedFilesByPage.values()) {
for (const file of files) imported.add(file)
}
return imported
}

isPageOutput(outPath: string) {
return this.contentIndex.getRelPathByOutPath(outPath) !== undefined
}

/** Pages marked to render on their next request since the last call. */
takeMarkedPageCount() {
const count = this.markedPages
Expand Down Expand Up @@ -268,8 +282,8 @@ export class IncrementalContentState {
return { changed, removed }
}

/** Picks up added or removed assets from the manifest. */
refreshAssets(assetRelPaths = Object.keys(this.input.getManifest().assets)) {
/** Source URL validation uses discovery, independently of copy exclusions. */
refreshAssets(assetRelPaths = this.input.getAssetRelPaths()) {
const { context } = this.input
this.updateContentRoutes(context.contentRoutes.withAssets(assetRelPaths))
}
Expand Down
7 changes: 5 additions & 2 deletions packages/ts-ssg/src/build/incremental/incremental.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,16 @@ HTML from earlier sessions. No background loop renders the rest of the site.
This is the canonical full build path:

- Resolves user hooks from `input.hooks`.
- Prepares output directory and copies static assets.
- Prepares the output directory and discovers static asset candidates.
- Discovers content, runs page generators, and rebuilds navigation, once
(`prepareContent`). Discovered pages join the URL index right away, so a
request during the build finds a new page.
- Renders all pages sequentially.
- Collects registered imports from pages and partials, then copies the remaining
static assets. Generated pages and script bundles own their output paths;
static copying and import cleanup must not overwrite or remove them.
- Writes styles and captures style outputs/signature.
- Discovers assets to build an authoritative manifest snapshot.
- Uses copied assets to build an authoritative manifest snapshot.
- Writes the manifest to disk with `writeManifest`.
- Emits `onBuildComplete` with the final result (including content/asset counts)
after manifest state is refreshed.
Expand Down
Loading
Loading