Skip to content

Commit

Permalink
Merge branch 'main' into 6048_eslint-flag
Browse files Browse the repository at this point in the history
  • Loading branch information
JerryWu1234 authored Jan 26, 2025
2 parents b0b17aa + 307bbd5 commit f2aca1c
Show file tree
Hide file tree
Showing 30 changed files with 269 additions and 85 deletions.
18 changes: 18 additions & 0 deletions .changeset/breezy-lizards-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'@builder.io/qwik-city': patch
---

FIX: MDX content now accepts `props`, including `components` that lets you use your own custom components

To add custom components to your MDX content, you can now do this:

```tsx
// routes/example/index.tsx
import Content from './markdown.mdx';
import MyComponent from '../../components/my-component/my-component';
import { component$ } from '@builder.io/qwik';

export default component$(() => <Content components={{ MyComponent }} />);
```

You can also use props in JS expressions. See https://mdxjs.com/docs/using-mdx/#props
5 changes: 5 additions & 0 deletions .changeset/bright-experts-sip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@builder.io/qwik': patch
---

tailwindcss v4 integration
5 changes: 5 additions & 0 deletions .changeset/cold-dogs-hunt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@builder.io/qwik': patch
---

fix: remove usage of `computedStyleMap`
5 changes: 5 additions & 0 deletions .changeset/long-jobs-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@builder.io/qwik-city': patch
---

FIX: mdx not rendering
5 changes: 5 additions & 0 deletions .changeset/witty-radios-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@builder.io/qwik': patch
---

fix: input's value is string when passing number
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ jobs:
packages/eslint-plugin-qwik/dist
packages/create-qwik/dist
# note that all inputs need to be listed here, including qwik, for correct cache invalidation
key: ${{ hashfiles('qwik-key.txt', 'rust-key.txt', 'packages/qwik-city/**/*', 'packages/qwik-labs/**/*', 'packages/qwik-react/**/*', 'packages/eslint-plugin-qwik/**/*', 'packages/create-qwik/**/*', '!**/*.unit.*') }}
key: ${{ hashfiles('qwik-key.txt', 'rust-key.txt', 'packages/qwik-city/**/*', 'packages/qwik-labs/**/*', 'packages/qwik-react/**/*', 'packages/eslint-plugin-qwik/**/*', 'packages/create-qwik/**/*', 'starters/apps/**/*', 'starters/features/**/*', 'starters/adapters/**/*', '!**/*.unit.*') }}
- run: 'echo ${{ steps.cache-others.outputs.cache-primary-key }} > others-key.txt'
- name: 'check cache: docs'
id: cache-docs
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/public/ecosystem/github.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/docs/src/routes/(ecosystem)/ecosystem.css
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,8 @@
.add-integration svg {
margin: auto;
}

[data-theme='dark'] [alt='GitHub'],
[data-theme='dark'] [alt='Twitter'] {
filter: invert(1);
}
3 changes: 1 addition & 2 deletions packages/docs/src/routes/demo/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function logQSymbols() {
}
console.info('QSymbol', symbol);
});
function interceptLogFn(name: 'debug' | 'error' | 'info' | 'log' | 'warn') {
for (const name of ['debug', 'error', 'info', 'log', 'warn'] as const) {
const delegate = console[name];
console[name] = function (...args: any[]) {
const li = document.createElement('li');
Expand All @@ -53,5 +53,4 @@ function logQSymbols() {
return delegate.apply(console, args);
};
}
(['debug', 'error', 'info', 'log', 'warn'] as const).forEach(interceptLogFn);
}
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,17 @@ The `bind:` is compiled away by the Qwik optimizer to a property set and an even
import { component$, useSignal } from '@builder.io/qwik';

export default component$(() => {
const count = useSignal(0);
const firstName = useSignal('');
const acceptConditions = useSignal(false);

return (
<form>
{/* For number inputs, use `valueAsNumber` instead of `value` to get the numeric value directly */}
<input type="number"
value={count.value}
onInput$={(_, el) => count.value = el.valueAsNumber }
/>
<input type="text"
value={firstName.value}
onInput$={(_, el) => firstName.value = el.value }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ const shallowStore = useStore(
> ```tsx
> delete store.propertyName;
> ```
> Be sure to access this property cautiously in the componet by using optional chaining ( ?. ):
> Be sure to access this property cautiously in the component by using optional chaining ( ?. ):
> ```tsx
> const propertyValue = store.propertyName?.value;
> ```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ export const Cmp = component$(() => {
## Scoped CSS

To use scoped CSS, you can use the `useStylesScoped$()` hook exported from `@builder.io/qwik`.
> `useStylesScoped$()` uses emojis to set a unique name on the selector. This is added by Qwik to avoid CSS name / selector clashes, and to ensure that the styles are correctly scoped as expected..




```tsx {4-8} title="src/components/MyComponent/MyComponent.tsx"
import { component$, useStylesScoped$ } from '@builder.io/qwik';
Expand Down
13 changes: 3 additions & 10 deletions packages/docs/src/routes/docs/integrations/tailwind/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ contributors:
- mrhoodz
- NickClark
- adamdbradley
updated_at: '2023-10-03T18:53:23Z'
- sreeisalso
updated_at: '2025-01-24T18:53:23Z'
created_at: '2023-04-06T21:28:28Z'
---

Expand Down Expand Up @@ -53,21 +54,13 @@ bun run qwik add tailwind

The previous command updates your app with the necessary dependencies.

It also adds new files to your project folder:

- `postcss.config.js`
- `tailwind.config.js`
- `.vscode/settings.json`

and modifies your `src/global.css` to include

```css title="src/global.css"

# global.css file

@tailwind base;
@tailwind components;
@tailwind utilities;
@import "tailwindcss";

...stuff...

Expand Down
21 changes: 16 additions & 5 deletions packages/qwik-city/src/buildtime/markdown/mdx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { BuildContext } from '../types';
import { parseFrontmatter } from './frontmatter';
import { getExtension } from '../../utils/fs';
import type { CompileOptions } from '@mdx-js/mdx';
import { createHash } from 'node:crypto';

export async function createMdxTransformer(ctx: BuildContext): Promise<MdxTransform> {
const { compile } = await import('@mdx-js/mdx');
Expand Down Expand Up @@ -69,11 +70,21 @@ export async function createMdxTransformer(ctx: BuildContext): Promise<MdxTransf
const file = new VFile({ value: code, path: id });
const compiled = await compile(file, options);
const output = String(compiled.value);
const addImport = `import { jsx } from '@builder.io/qwik';\n`;
const newDefault = `
const WrappedMdxContent = () => {
const content = _createMdxContent({});
return typeof MDXLayout === 'function' ? jsx(MDXLayout, {children: content}) : content;
const hasher = createHash('sha256');
const key = hasher
.update(output)
.digest('base64')
.slice(0, 8)
.replace('+', '-')
.replace('/', '_');
const addImport = `import { jsx, _jsxC, RenderOnce } from '@builder.io/qwik';\n`;
const newDefault = `
const WrappedMdxContent = (props = {}) => {
const content = _jsxC(RenderOnce, {children: _jsxC(_createMdxContent, props, 3, null)}, 3, ${JSON.stringify(key)});
if (typeof MDXLayout === 'function'){
return jsx(MDXLayout, {children: content});
}
return content;
};
export default WrappedMdxContent;
`;
Expand Down
26 changes: 16 additions & 10 deletions packages/qwik-city/src/buildtime/markdown/mdx.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('mdx', async () => {

expect(result).toMatchInlineSnapshot(`
{
"code": "import { jsx } from '@builder.io/qwik';
"code": "import { jsx, _jsxC, RenderOnce } from '@builder.io/qwik';
import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "@builder.io/qwik/jsx-runtime";
export const headings = [{
"text": "Hello",
Expand Down Expand Up @@ -60,10 +60,13 @@ describe('mdx', async () => {
})]
});
}
const WrappedMdxContent = () => {
const content = _createMdxContent({});
return typeof MDXLayout === 'function' ? jsx(MDXLayout, {children: content}) : content;
const WrappedMdxContent = (props = {}) => {
const content = _jsxC(RenderOnce, {children: _jsxC(_createMdxContent, props, 3, null)}, 3, "eB2HIyA1");
if (typeof MDXLayout === 'function'){
return jsx(MDXLayout, {children: content});
}
return content;
};
export default WrappedMdxContent;
",
Expand Down Expand Up @@ -95,7 +98,7 @@ export default function Layout({ children: content }) {

expect(result).toMatchInlineSnapshot(`
{
"code": "import { jsx } from '@builder.io/qwik';
"code": "import { jsx, _jsxC, RenderOnce } from '@builder.io/qwik';
import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "@builder.io/qwik/jsx-runtime";
export const headings = [{
"text": "Hello",
Expand Down Expand Up @@ -134,10 +137,13 @@ export default function Layout({ children: content }) {
})]
});
}
const WrappedMdxContent = () => {
const content = _createMdxContent({});
return typeof MDXLayout === 'function' ? jsx(MDXLayout, {children: content}) : content;
const WrappedMdxContent = (props = {}) => {
const content = _jsxC(RenderOnce, {children: _jsxC(_createMdxContent, props, 3, null)}, 3, "UdQmQWC3");
if (typeof MDXLayout === 'function'){
return jsx(MDXLayout, {children: content});
}
return content;
};
export default WrappedMdxContent;
",
Expand Down
2 changes: 1 addition & 1 deletion packages/qwik/src/core/render/jsx/types/jsx-generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ type SpecialAttrs = {
* For type: HTMLInputTypeAttribute, excluding 'button' | 'reset' | 'submit' | 'checkbox' |
* 'radio'
*/
'bind:value'?: Signal<string | undefined>;
'bind:value'?: Signal<string | undefined | number>;
enterKeyHint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send' | undefined;
height?: Size | undefined;
max?: number | string | undefined;
Expand Down
10 changes: 8 additions & 2 deletions packages/qwik/src/core/state/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,20 @@ export class ReadWriteProxyHandler implements ProxyHandler<TargetType> {
: a;
});
}

getOwnPropertyDescriptor(
target: TargetType,
prop: string | symbol
): PropertyDescriptor | undefined {
const descriptor = Reflect.getOwnPropertyDescriptor(target, prop);

if (isArray(target) || typeof prop === 'symbol') {
return Object.getOwnPropertyDescriptor(target, prop);
return descriptor;
}

if (descriptor && !descriptor.configurable) {
return descriptor;
}

return {
enumerable: true,
configurable: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const Greeter = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{
"value": value,
"onInput$": /*#__PURE__*/ inlinedQrl((_, elm)=>{
const [value] = useLexicalScope();
return value.value = elm.value;
return value.value = elm.type == "number" ? elm.valueAsNumber : elm.value;
}, "s_6IZeYpXCNXA", [
value
])
Expand All @@ -53,7 +53,7 @@ export const Greeter = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{
"checked": checked,
"onInput$": /*#__PURE__*/ inlinedQrl((_, elm)=>{
const [checked] = useLexicalScope();
return checked.value = elm.checked;
return checked.value = elm.type == "number" ? elm.valueAsNumber : elm.checked;
}, "s_JPI3bLCVnso", [
checked
])
Expand All @@ -62,7 +62,7 @@ export const Greeter = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{
"stuff": stuff,
"onChange$": /*#__PURE__*/ inlinedQrl((_, elm)=>{
const [stuff] = useLexicalScope();
return stuff.value = elm.stuff;
return stuff.value = elm.type == "number" ? elm.valueAsNumber : elm.stuff;
}, "s_eyREJ0lZTFw", [
stuff
])
Expand Down
62 changes: 52 additions & 10 deletions packages/qwik/src/optimizer/core/src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1298,17 +1298,59 @@ impl<'a> QwikTransform<'a> {
),
),
op: ast::AssignOp::Assign,
right: Box::new(ast::Expr::Member(
ast::MemberExpr {
obj: Box::new(ast::Expr::Ident(elm)),
prop: ast::MemberProp::Ident(
ast::IdentName::new(
prop_name, DUMMY_SP,
),
),
right: Box::new(ast::Expr::Cond(ast::CondExpr {
test: Box::new(ast::Expr::Bin(ast::BinExpr {
left: Box::new(ast::Expr::Member(
ast::MemberExpr {
obj: Box::new(ast::Expr::Ident(
elm.clone(),
)),
prop: ast::MemberProp::Ident(
ast::IdentName::new(
"type".into(),
DUMMY_SP,
),
),
span: DUMMY_SP,
},
)),
span: DUMMY_SP,
},
)),
op: ast::BinaryOp::EqEq,
right: Box::new(ast::Expr::Lit(
ast::Lit::Str(ast::Str {
value: "number".into(),
span: DUMMY_SP,
raw: None,
}),
)),
})),
cons: Box::new(ast::Expr::Member(
ast::MemberExpr {
obj: Box::new(ast::Expr::Ident(
elm.clone(),
)),
prop: ast::MemberProp::Ident(
ast::IdentName::new(
"valueAsNumber".into(),
DUMMY_SP,
),
),
span: DUMMY_SP,
},
)),
alt: Box::new(ast::Expr::Member(
ast::MemberExpr {
obj: Box::new(ast::Expr::Ident(elm)),
prop: ast::MemberProp::Ident(
ast::IdentName::new(
prop_name, DUMMY_SP,
),
),
span: DUMMY_SP,
},
)),
span: DUMMY_SP,
})),
span: DUMMY_SP,
}),
))),
Expand Down
10 changes: 5 additions & 5 deletions packages/qwik/src/optimizer/src/plugins/image-size-runtime.html
Original file line number Diff line number Diff line change
Expand Up @@ -312,11 +312,11 @@ <h2 id="title"></h2>
const browserArea = rect.width * rect.height;
if (!node.hasAttribute('width') || !node.hasAttribute('height')) {
skip = true;
const computedStyles = node.computedStyleMap();
const hasAspect = computedStyles.get('aspect-ratio').toString() !== 'auto';
const hasWidth = isDefinedUnit(computedStyles.get('width').toString());
const hasHeight = isDefinedUnit(computedStyles.get('height').toString());
const isAbsolute = computedStyles.get('position').toString() === 'absolute';
const computedStyles = getComputedStyle(node);
const hasAspect = computedStyles.getPropertyValue('aspect-ratio').toString() !== 'auto';
const hasWidth = isDefinedUnit(computedStyles.getPropertyValue('width').toString());
const hasHeight = isDefinedUnit(computedStyles.getPropertyValue('height').toString());
const isAbsolute = computedStyles.getPropertyValue('position').toString() === 'absolute';
layoutInvalidation =
browserArea > 1000 && !isAbsolute && !hasAspect && (!hasWidth || !hasHeight);
}
Expand Down
Loading

0 comments on commit f2aca1c

Please sign in to comment.