diff --git a/prop/prop.view.tree b/prop/prop.view.tree
index 3d89e5d..3e338a9 100644
--- a/prop/prop.view.tree
+++ b/prop/prop.view.tree
@@ -29,6 +29,14 @@ $hyoo_studio_prop $mol_view
 						hint @ \Changeable
 						Icon <= Next_icon $mol_icon_atom_variant
 						checked? <=> changeable? false
+					<= Styles $mol_check_icon
+						hint @ \Styles
+						Icon <= Styles_icon $mol_icon_language_css3
+						checked? <=> styles_opened? false
+					<= Behavior $mol_check_icon
+						hint @ \Behavior
+						Icon <= Behavior_icon $mol_icon_language_javascript
+						checked? <=> behavior_opened? false
 			content <= prop_content /
 				<= Value $hyoo_studio_value
 					hide_tools true
diff --git a/prop/prop.view.ts b/prop/prop.view.ts
index 2218114..2feac96 100644
--- a/prop/prop.view.ts
+++ b/prop/prop.view.ts
@@ -37,6 +37,39 @@ namespace $.$$ {
 
 			return Boolean( sign_obj.next )
 		}
+
+		@ $mol_mem
+		styles_opened( next?: boolean ) {
+			if (next !== undefined) {
+				this.$.$mol_state_arg.value('raw', next ? '' : null)
+				this.$.$mol_state_arg.value('raw_type', next ? 'Styles' : null)
+				this.$.$mol_state_arg.value('raw_prop', next ? this.name() : null)
+			}
+
+			return this.$.$mol_state_arg.value('raw_prop') === this.name() && this.$.$mol_state_arg.value('raw') === '' && this.$.$mol_state_arg.value('raw_type') === 'styles'
+		}
+
+		@ $mol_mem
+		behavior_opened( next?: boolean ) {
+			if (next !== undefined) {
+				this.$.$mol_state_arg.value('raw', next ? '' : null)
+				this.$.$mol_state_arg.value('raw_type', next ? 'Behavior' : null)
+				this.$.$mol_state_arg.value('raw_prop', next ? this.name() : null)
+			}
+
+			return this.$.$mol_state_arg.value('raw_prop') === this.name() && this.$.$mol_state_arg.value('raw') === '' && this.$.$mol_state_arg.value('raw_type') === 'behavior'
+		}
+
+		@ $mol_mem
+		prop_tools() {
+			return [
+				this.Value_tools(),
+				... this.Value().type() === 'object' ? [this.Styles()] : [],
+				this.Behavior(),
+				this.Key(),
+				this.Next(),
+			]
+		}
 		
 		prop_content() {
 			switch (this.Value().type()) {
@@ -71,6 +104,7 @@ namespace $.$$ {
 			}
 		}
 
+			
 		@ $mol_mem
 		expanded(next?: boolean): boolean {
 
diff --git a/studio.view.css.ts b/studio.view.css.ts
index 5d1d999..e7493fb 100644
--- a/studio.view.css.ts
+++ b/studio.view.css.ts
@@ -52,6 +52,17 @@ namespace $.$$ {
 			},
 		},
 
+		Source_type: {
+			flex: {
+				grow: 1,
+			},
+			Switch: {
+				flex: {
+					grow: 0,
+				},
+			},
+		},
+
 		Source_page: {
 			flex: {
 				basis: rem( 40 ),
@@ -61,6 +72,14 @@ namespace $.$$ {
 			},
 		},
 
+		Source_page_list: {
+			width: '100%',
+		},
+
+		Source_prop_name: {
+			padding: $mol_gap.block,
+		},
+
 		Preview: {
 			flex: {
 				basis: rem( 40 ),
diff --git a/studio.view.tree b/studio.view.tree
index 155f3dd..7c9a8ac 100644
--- a/studio.view.tree
+++ b/studio.view.tree
@@ -81,10 +81,35 @@ $hyoo_studio $mol_book2
 		<= Source_page $mol_page
 			title @ \Raw Code
 			body /
-				<= Source $mol_textarea
-					hint \$hyoo_studio_example $mol_view
-					sidebar_showed true
-					value?val <=> source?val \$hyoo_studio_example $mol_view
+				<= Source_page_list $mol_list rows <= source_page_body /
+					<= Source_prop_switch $mol_view
+						sub /
+							<= Source_prop_name $mol_paragraph title <= source_prop_name \The property is editing: {prop_name}
+							<= Source_prop_exit $mol_button_minor
+								title @ \Show all
+								click? <=> source_prop_exit? null
+					<= Source_type $mol_deck
+						current? <=> soure_type_current? \0
+						items /
+							<= Source $mol_textarea
+								title \Composition
+								hint \$hyoo_studio_example $mol_view
+								sidebar_showed true
+								value? <=> source_tree? \$hyoo_studio_example $mol_view
+							<= Source_css $mol_textarea
+								title \Styles
+								hint \
+								sidebar_showed true
+								value? <=> source_css_switch? <=> source_css? \
+							<= Source_js $mol_textarea
+								title \Behavior
+								hint \
+								sidebar_showed true
+								value? <=> source_js_switch? <=> source_js? \
+									\class {self} extends $.{self} {
+									\// Don't delete the first and last lines
+									\// Don't delete auto-generated comments
+									\}
 		<= Preview $mol_frame
 			title @ \Preview
 			uri <= pack
diff --git a/studio.view.ts b/studio.view.ts
index 2bdbcdd..99a3300 100644
--- a/studio.view.ts
+++ b/studio.view.ts
@@ -36,8 +36,18 @@ namespace $.$$ {
 		}
 		
 		@ $mol_mem
-		source( next?: string ): string {
-			return this.$.$mol_state_arg.value( 'source', next ) ?? super.source()
+		source_tree( next?: string ): string {
+			return this.$.$mol_state_arg.value( 'source', next ) ?? super.source_tree()
+		}
+
+		@ $mol_mem
+		source_css( next?: string ): string {
+			return this.$.$mol_state_arg.value( 'source_css', next ) ?? '/* Don\'t delete auto-generated comments */\n'
+		}
+
+		@ $mol_mem
+		source_js( next?: string ): string {
+			return this.$.$mol_state_arg.value( 'source_js', next ) ?? super.source_js()
 		}
 
 		@ $mol_mem
@@ -56,7 +66,6 @@ namespace $.$$ {
 					</body>
 				</html>
 			`
-			
 		}
 		
 		@ $mol_mem
@@ -108,7 +117,7 @@ namespace $.$$ {
 		@ $mol_mem
 		tree( next?: $mol_tree2 ) {
 			
-			const source = this.source( next && next.toString() ).replace( /\n?$/, '\n' )
+			const source = this.source_tree( next && next.toString() ).replace( /\n?$/, '\n' )
 			
 			const tree = this.$.$mol_view_tree2_normalize(
 				this.$.$mol_tree2_from_string( source )
@@ -155,7 +164,7 @@ namespace $.$$ {
 			
 			return this.readme_selected( next )
 		}
-		
+
 		@ $mol_mem
 		self_code() {
 			
@@ -172,6 +181,9 @@ namespace $.$$ {
 			return `
 				$.$mol_wire_auto = parent.$mol_wire_auto
 				$.${ this.self() } = ${ code }
+				$.${ this.self() } = ${this.source_js().replaceAll('{self}', this.self())}
+				;${ this.source_js_decorators() };
+				$.$mol_style_attach(${ this.self() }, \`${ this.source_css().replaceAll('{self}', this.self().slice(1)) }\`)
 			`
 		}
 		
@@ -320,5 +332,107 @@ namespace $.$$ {
 			
 			return this.props_all().select( sign ).kids[0] ?? null
 		}
+
+		@ $mol_mem
+		soure_type_current( next?: string ) {
+			const options = Object.entries(this.Source_type().switch_options())
+			if (next === undefined) {
+				const title = this.$.$mol_state_arg.value('raw_type')
+				const [value] = options.find(([value, label]) => label === title) ?? ['0']
+				return value
+			}
+
+			const next_title = options[Number(next)]?.[1]
+			this.$.$mol_state_arg.value('raw_type', next_title ?? options[0][1])
+			return next
+		}
+
+		@ $mol_mem_key
+		source_css_prop( prop_name: string, next?: string ) {
+			const tag = `/*${prop_name}*/`
+			const [before = '', prop_styles = '', after = ''] = this.source_css().split(tag)
+
+			if (next === undefined) {
+				return prop_styles.trim() || `[{self}_${prop_name.toLowerCase()}] {\n\t\n}`
+			}
+
+			const all = [before, tag, next.trim(), tag, after].join('\n').trim().replaceAll(/\n{2,}/g, '\n\n')
+			this.source_css(all)
+			return next.trim()
+		}
+
+		@ $mol_mem
+		source_css_switch( next?: string ) {
+			const prop_name = this.$.$mol_state_arg.value('raw_prop')
+
+			if (!prop_name) return this.source_css(next)
+
+			return this.source_css_prop(prop_name, next)
+		}
+
+		@ $mol_mem
+		source_js_decorators() {
+			const list = new Array<string>()
+
+			const add = (prop_name: string, key: boolean, next: boolean) => {
+				if (!key && !next) return
+				if (this.source_js().includes(`/*${prop_name}*/`))
+				list.push(`($mol_mem${key ? '_key' : ''}(($.${ this.self() }.prototype), "${ prop_name }"));`)
+			}
+
+			this.props().forEach(prop => add(prop.name(), prop.multiple(), prop.changeable()))
+
+			return list.join('\n')
+		}
+
+		@ $mol_mem_key
+		source_js_prop( prop_name: string, next?: string ) {
+			console.log(11111111)
+			console.log(this.source_js_decorators())
+			const lines = this.source_js().split('\n')
+			const class_begin = lines.shift()
+			const class_end = lines.pop()
+
+			const tag = `/*${prop_name}*/`
+			const [before = '', prop_js = '', after = ''] = lines.join('\n').split(tag)
+
+			const multiple = this.Prop(prop_name).multiple()
+			const changeable = this.Prop(prop_name).changeable()
+			const params = [...multiple ? ['key'] : [], ...changeable ? ['next'] : []].join(', ')
+			if (next === undefined) {
+				return prop_js.trim().replace(new RegExp(`${prop_name}\\s*\\(.*\\)`), `${prop_name} (${params})`) || `${prop_name} (${params}) {\n\t\n}`
+			}
+
+			const all = [class_begin, before, tag, next.trim(), tag, after, class_end].join('\n').trim().replaceAll(/\n{2,}/g, '\n\n')
+			this.source_js(all)
+			return next.trim()
+		}
+
+		@ $mol_mem
+		source_js_switch( next?: string ) {
+			const prop_name = this.$.$mol_state_arg.value('raw_prop')
+
+			if (!prop_name) return this.source_js(next)
+
+			return this.source_js_prop(prop_name, next)
+		}
+
+		source_prop_name() {
+			return super.source_prop_name().replaceAll('{prop_name}', this.$.$mol_state_arg.value('raw_prop')!)
+		}
+
+		@ $mol_action
+		source_prop_exit() {
+			this.$.$mol_state_arg.value('raw_prop', null)
+		}
+
+		@ $mol_mem
+		source_page_body() {
+			const show = this.$.$mol_state_arg.value('raw_prop') !== null && this.$.$mol_state_arg.value('raw_type') !== 'view.tree'
+			return [
+				... show ? [this.Source_prop_switch()] : [],
+				this.Source_type(),
+			]
+		}
 	}
 }