8000 Implement RFC 13 Passing CSS custom properties to components by tanhauhau · Pull Request #6237 · sveltejs/svelte · GitHub
[go: up one dir, main page]

Skip to content

Implement RFC 13 Passing CSS custom properties to components #6237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 30, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
implement rfc 13
  • Loading branch information
tanhauhau committed Apr 28, 2021
commit e930d77ed5aa3d9c10aea7a5ba7b8a6e542e65d1
5 changes: 5 additions & 0 deletions src/compiler/compile/nodes/InlineComponent.ts
8000
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default class InlineComponent extends Node {
bindings: Binding[] = [];
handlers: EventHandler[] = [];
lets: Let[] = [];
css_custom_properties: Attribute[] = [];
children: INode[];
scope: TemplateScope;

Expand Down Expand Up @@ -46,6 +47,10 @@ export default class InlineComponent extends Node {
});

case 'Attribute':
if (node.name.startsWith('--')) {
this.css_custom_properties.push(new Attribute(component, this, scope, node));
break;
}
// fallthrough
case 'Spread':
this.attributes.push(new Attribute(component, this, scope, node));
Expand Down
66 changes: 62 additions & 4 deletions src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts
8000
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { extract_names } from 'periscopic';
import mark_each_block_bindings from '../shared/mark_each_block_bindings';
import { string_to_member_expression } from '../../../utils/string_to_member_expression';
import SlotTemplate from '../../../nodes/SlotTemplate';
import { is_head } from '../shared/is_head';

type SlotDefinition = { block: Block; scope: TemplateScope; get_context?: Node; get_changes?: Node };

Expand Down Expand Up @@ -63,6 +64,10 @@ export default class InlineComponentWrapper extends Wrapper {
}
});

this.node.css_custom_properties.forEach(attr => {
block.add_dependencies(attr.dependencies);
});

this.var = {
type: 'Identifier',
name: (
Expand Down Expand Up @@ -146,6 +151,12 @@ export default class InlineComponentWrapper extends Wrapper {
}
}

const has_css_custom_properties = this.node.css_custom_properties.length > 0;
const css_custom_properties_wrapper = has_css_custom_properties ? block.get_unique_name('div') : null;
if (has_css_custom_properties) {
block.add_variable(css_custom_properties_wrapper);
}

const initial_props = this.slots.size > 0
? [
p`$$slots: {
Expand Down Expand Up @@ -491,17 +502,64 @@ export default class InlineComponentWrapper extends Wrapper {
${munged_handlers}
`);

if (has_css_custom_properties) {
block.chunks.create.push(b`${css_custom_properties_wrapper} = @element("div");`);
block.chunks.hydrate.push(b`@set_style(${css_custom_properties_wrapper}, "display", "contents");`);
this.node.css_custom_properties.forEach(attr => {
const dependencies = attr.get_dependencies();
const should_cache = attr.should_cache();
const last = should_cache && block.get_unique_name(`${attr.name.replace(/[^a-zA-Z_$]/g, '_')}_last`);
if (should_cache) block.add_variable(last);
const value = attr.get_value(block);
const init = should_cache ? x`${last} = ${value}` : value;

block.chunks.hydrate.push(b`@set_style(${css_custom_properties_wrapper}, "${attr.name}", ${init});`);
if (dependencies.length > 0) {
let condition = block.renderer.dirty(dependencies);
if (should_cache) condition = x`${condition} && (${last} !== (${last} = ${value}))`;

block.chunks.update.push(b`
if (${condition}) {
@set_style(${css_custom_properties_wrapper}, "${attr.name}", ${should_cache ? last : value});
}
`);
}
});
}
block.chunks.create.push(b`@create_component(${name}.$$.fragment);`);

if (parent_nodes && this.renderer.options.hydratable) {
let nodes = parent_nodes;
if (has_css_custom_properties) {
nodes = block.get_unique_name(`${css_custom_properties_wrapper.name}_nodes`);
block.chunks.claim.push(b`
${css_custom_properties_wrapper} = @claim_element(${parent_nodes}, "DIV", { style: true })
var ${nodes} = @children(${css_custom_properties_wrapper});
`);
}
block.chunks.claim.push(
b`@claim_component(${name}.$$.fragment, ${parent_nodes});`
b`@claim_component(${name}.$$.fragment, ${nodes});`
);
}

block.chunks.mount.push(
b`@mount_component(${name}, ${parent_node || '#target'}, ${parent_node ? 'null' : '#anchor'});`
);
if (has_css_custom_properties) {
if (parent_node) {
block.chunks.mount.push(b`@append(${parent_node}, ${css_custom_properties_wrapper})`);
if (is_head(parent_node)) {
block.chunks.destroy.push(b`@detach(${css_custom_properties_wrapper});`);
}
} else {
block.chunks.mount.push(b`@insert(#target, ${css_custom_properties_wrapper}, #anchor);`);
// TODO we eventually need to consider what happens to elements
// that belong to the same outgroup as an outroing element...
block.chunks.destroy.push(b`if (detaching) @detach(${css_custom_properties_wrapper});`);
}
block.chunks.mount.push(b`@mount_component(${name}, ${css_custom_properties_wrapper}, null);`);
} else {
block.chunks.mount.push(
b`@mount_component(${name}, ${parent_node || '#target'}, ${parent_node ? 'null' : '#anchor'});`
);
}

block.chunks.intro.push(b`
@transition_in(${name}.$$.fragment, #local);
Expand Down
17 changes: 17 additions & 0 deletions src/compiler/compile/render_ssr/handlers/InlineComponent.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { string_literal } from '../../utils/stringify';
import { get_attribute_value } from './shared/get_attribute_value';
import Renderer, { RenderOptions } from '../Renderer';
import InlineComponent from '../../nodes/InlineComponent';
import { p, x } from 'code-red';
Expand Down Expand Up @@ -86,5 +87,21 @@ export default function(node: InlineComponent, renderer: Renderer, options: Rend
${slot_fns}
}`;

if (node.css_custom_properties.length > 0) {
renderer.add_string('<div style="display: contents; ');
node.css_custom_properties.forEach((attr, index) => {
renderer.add_string(attr.name);
renderer.add_string(':');
renderer.add_expression(get_attribute_value(attr));
renderer.add_string(';');
if (index < node.css_custom_properties.length - 1) renderer.add_string(' ');
});
renderer.add_string('">');
}

renderer.add_expression(x`@validate_component(${expression}, "${node.name}").$$render($$result, ${props}, ${bindings}, ${slots})`);

if (node.css_custom_properties.length > 0) {
renderer.add_string('</div>');
}
}
0